Communicating a QThread and Custom Widget in QT C++

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.

In this article we are going to use one of my previous component. You can see how can we create our custom widget. You can reach that article via below link:

How to Create Custom Widget in QT C++

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);
};
  • As you can see above we have created TheWatch class and and derived from QWidget class. Then we added a QLabel inside it to show watch.
  • Then we added our signal to make a connection from outside. Also we have a slot to update value of QLabel.

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);

};
  • Also our class has a signal to emit at every specified time for updating.

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);
    }
}
  • As you can see above we have emitted our signal at every second. This signal will be connected our widget's update method.

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();
}
Our program is ready now. You can see the output of example at below image. QT C++ Custom Digital Watch Widget Example output

That is all in this article.

Burak Hamdi TUFAN


Tags


Share this Post

Send with Whatsapp

Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

  • There is no comment. Be the owner of first comment...