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

QThread: what am I missing here?



  • Hi all -

    I thought I had a handle on using QThreads, but this minimal example doesn't work as I expect:

    #include "widget.h"
    #include "worker.h"
    
    #include <QApplication>
    #include <QDebug>
    #include <QThread>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget *widget;
        Worker *worker;
        QThread *thread(nullptr);
        int rc;
    
        widget = new Widget();
        worker = new Worker();
        thread = new QThread(nullptr);
    
        QObject::connect(worker, &Worker::askForMessageBox, widget, &Widget::displayMessageBox);
    
        widget->show();
        worker->moveToThread(thread);
        thread->start();
    
        rc = a.exec();
        qDebug() << rc;
        return rc;
    }
    
    #include <QDebug>
    #include "worker.h"
    
    Worker::Worker(QObject *parent) : QObject(parent)
    {
    }
    void Worker::start()
    {
        emit askForMessageBox();
    }
    

    When I run this in the debugger, my start() never gets called. What am I missing?

    Thanks...

    EDIT:

    I was missing this:

        QObject::connect(thread, &QThread::started, worker, &Worker::start);
    


  • Side-note: you are leaking every single object in this example



  • It's probably not clear from the example, but (one instance each of) thread, widget and worker all need to exist for the life of the process.



  • @mzimmers
    Up to you, but you're "supposed" to delete them just before exit. Makes using valgrind a lot easier when you want to detect other leaks in the future :)

    Separate point: for this particular code you could put them all on stack instead of heap, then it wouldn't be an issue.



  • Don't let the OS cleanup after you, it's rude, it works hard already and is never appreciated. For once you could pick up your own memory instead of always locking yourself in your room listening to 8bit music at the maximum volume possible!

    Give a parent to the objects in the main thread (widget and thread) and QObject::connect(thread, &QThread::finished, worker, &Worker::deleteLater);



  • "But Ma...it's not even a school night! Geez..."

    But, you're right of course about picking up memory. You don't want to step on those bits barefoot. The 0s are OK, but the 1s are kind of sharp.

    What does one ordinarily use as a parent for top level objects like my widget and thread? I guess I could use the worker, since if I use your connect example, I know it will be destroyed, but I'm guessing there's a better alternative?


  • Lifetime Qt Champion

    @mzimmers Why do you use heap allocation in main()? Simply allocate on the stack then you do not have to care about leaks.



  • As mentioned the top level usually is stack-allocated, alternatively you can use the QApplication object as parent


Log in to reply