Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Understanding how to start a Qthread



  • Hi,
    Just started using QT from last week. I am trying to start a thread and verify if its working by incrementing a variable. But, the thread is not starting, Not able to identify what is the flaw.
    Here is the .h file of mythread class

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include <QObject>
    #include<QThread>
    #include"mainwindow.h"
    
    class mythread:public QObject
    {
        Q_OBJECT
    public:
        explicit mythread(QObject *parent = 0);
        ~mythread();
    private:
    int count;
    public slots:
        void counter();
    signals:
        void finished(int i);
    
    };
    
    #endif // MYTHREAD_H
    

    Here is the mythread.cpp

    #include "mythread.h"
    #include"mainwindow.h"
    
    
    
    mythread::mythread(QObject *parent) : QObject(parent)
    {
        count=0x00;
    }
    
    mythread::~mythread()
    {
    
    }
    
    void mythread::counter()
    {
        count++;
        emit finished(count);
    
    }
    

    Here is .h file of mainwindow

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include<mythread.h>
    #include<QThread>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    public slots:
        void updatecount(int dat);
    
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    And here is mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QThread>
    #include"mythread.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        QThread *thread = new QThread;
        mythread *worker = new mythread();
        worker->moveToThread(thread);
        connect(thread,SIGNAL(started()),worker,SLOT(counter()));
        connect(worker,SIGNAL(finished(int)),this,SLOT(updatecount(int)));
        thread->start();
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::updatecount(int dat)
    {
        ui->lcdNumber->display(dat);
    }
    
    

    The logic is, every time the count variable is incremented, a signal containing the value of the count variable is emitted. This signal is caught by the slot updatecount and displayed on the lcd. Since, its a thread the count variable should continuously increment and display the counts. But this is not happening. I don't get what I am doing wrong, any support regarding this would be helpful.


  • Moderators

    @weedy said:

    Since, its a thread the count variable should continuously increment and display the counts

    That's a weird assumption. A thread is not automatically a loop. What happens is:

    • Your thread starts
    • counter() is called in it
    • the thread count is increased (to 1) and finished(1) is emitted
    • updatecount(1) is called and 1 goes to the display
      That's it.
      At this point you've got your usual main thread and a second thread with an event loop that does nothing.
      There's no loop that calls counter() anywhere in your program.

    Btw. your thread and worker objects are never destroyed so they leak memory. Also, you don't have any condition for the worker thread to exit event loop so it will spin empty in the background and print a warning at the app exit.



  • That's exactly what happened. After reading your answer and a little bit about threads, it cleared the
    ambiguity. I had assumed that these functions are called repeatedly once the thread starts. I did not get the last part about worker thread exiting the event loop. Could you please elaborate a little on that?


  • Moderators

    Qt works with so-called event loops.
    There's usually one in your main() started with a.exec();. this method runs a loop in which it processes and dispatches incoming events, signals etc. By default it exits when last window is closed (see docs for details).
    QThread::start() does basically the same as a.exec(), just in another thread. It starts a loop that processes events and signals of objects in that thread. The difference is that this event loop doesn't quit when last window is closed. You need to manually exit that loop with either exit or quit. Otherwise it will run until your app terminates, but that's not a clean exit. You should quit the loop yourself which will in turn terminate the thread.



  • That clears it. Thanks!



  • How do I mark this post solved?.




Log in to reply