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

QThread, signals and lambdas



  • It took me a while to figure out that this causes a crash. Linguistically, it is opaque to me. Could someone please tell me why this isn't good, please?

    MyClass::MyClass
        :   QWidget()
        ,   myObject(new MyObject)
    {
        // Causes memory corruption, intermittent crashes, QTimer warnings, etc.
    //    QObject::connect(myObject, MyObject::mySignal, []() {
    //        QMessageBox mb;
    //        mb.setText("Hello world");
    //        mb.exec();
    //    });
        //this works fine
        QObject::connect(myObject, MyObject::mySignal, this, &MyClass::handleMySignal);
        QThread *thr = new QThread;
        QObject::connect(myObject, MyObject::destroyed, thr, QThread::quit);
        QObject::connect(thr, &QThread, &QThread::finished, thr, &QThread::deleteLater);
        myObject->moveToThread(thr);
        thr->start();
    }
    
    void MyClass::handleMySignal()
    {
        QMessageBox mb;
        mb.setText("Hello world");
        mb.exec();
    }
    
    

  • Lifetime Qt Champion

    This is because the lambda version is executed in the thread, not in the main thread which is not allowed for gui operations.
    Pass 'this' as third parameter so the lambda gets executed in the main thread (= where 'this' lives in)





  • @Jeff-Barnes To solve the issue, you should use this as receiver of the signal, so the lambda will be executed in the right thread:

    QObject::connect(myObject, MyObject::mySignal, this, []() {
          QMessageBox mb;
          mb.setText("Hello world");
          mb.exec();
      });
    

Log in to reply