Communicating a QThread and Custom Widget in QT C++
Hello everyone, in this article we are going to make a custom designed QWidget communicate with a background QThread. We are going to design our own widget and background thread here.Let's begin.
Firstly we create a Qt Form Class and I named it as CustomDigitalWatch. So this will create customdigitalwatch.h header file and customdigitalwatch.cpp source files. I will not create new files for each class and declare all of classes in same source files.
Let's create our Digital Watch class first in out header file.
class TheWatch : public QWidget
{
Q_OBJECT
public:
TheWatch(QWidget *parent = nullptr);
private :
QLabel *lblWatch;
private slots:
void writeUpdatedTime(QString timetext);
signals:
void timeUpdated(QString timetext);
};
Now create our background thread class. In here we are going to create a class derived from QThread class. and implement run() virtual method of QThread class.
class WatchUpdaterThread : public QThread
{
Q_OBJECT
public:
WatchUpdaterThread(QWidget *parent);
void run();
signals:
void updateTimeFromThread(QString timetext);
};
And here is our form class. In here under private access specifier we declared our thread and custom widgets class.
class CustomDigitalWatch : public QWidget
{
Q_OBJECT
public:
explicit CustomDigitalWatch(QWidget *parent = nullptr);
~CustomDigitalWatch();
private:
Ui::CustomDigitalWatch *ui;
TheWatch *theWatch;
WatchUpdaterThread *watchUpdaterThread;
};
Until here our header is ready. Now we need to make implementations of above classes. In our customdigitalwatch.cpp source file we are going to make all implementations of prototype methods.
Now first make our TheWatch digital watch widget implementation. First we will create a HBoxLayour and we will add our QLabel into this widget.
TheWatch::TheWatch(QWidget *parent)
{
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setMargin(0);
lblWatch = new QLabel(QString("00:00:00"));
QString strFont = "font: 75 108pt 'Comic Sans MS',";
lblWatch->setStyleSheet(strFont);
lblWatch->setAlignment(Qt::AlignCenter);
lblWatch->setMargin(0); // to stretch the widget
qDebug() << "TheWatch Constructor";
layout->addWidget(lblWatch);
}
void TheWatch::writeUpdatedTime(QString timetext)
{
lblWatch->setText(timetext);
}
Then we made our thread implementation. In here we have implemented run() method. This method will be invoked automatically when the thread started.
WatchUpdaterThread::WatchUpdaterThread(QWidget *parent)
{
}
void WatchUpdaterThread::run()
{
while(true)
{
emit updateTimeFromThread(QDateTime::currentDateTime().toString("hh:mm:ss"));
qDebug() << QDateTime::currentDateTime().toString("hh:mm:ss");
QThread::sleep(1);
}
}
Lastlty, we need to initialize our widget and thread. Then we need to connect the signal of thread and slot of widget. I will make it in form class constructor.
CustomDigitalWatch::CustomDigitalWatch(QWidget *parent) :
QWidget(parent),
ui(new Ui::CustomDigitalWatch)
{
ui->setupUi(this);
theWatch = new TheWatch();
watchUpdaterThread = new WatchUpdaterThread(this);
QGridLayout *layout = new QGridLayout;
layout->setMargin(0);
layout->addWidget(theWatch);
ui->widgetWatch->setLayout(layout);
connect( watchUpdaterThread, SIGNAL(updateTimeFromThread(QString)), theWatch, SLOT(writeUpdatedTime(QString)) );
watchUpdaterThread->start();
}
You can reach form class on Github via below link.
https://github.com/thecodeprogram/TheSingleFiles/tree/master/qt_cpp_communicate_qthread_and_custom_widget
That is all in this article.
Burak Hamdi TUFAN
Comments