How to execute a functor or a lambda in a given thread in Qt, GCD-style?

后端 未结 5 1687
萌比男神i
萌比男神i 2020-11-22 05:11

In ObjC with GCD, there is a way of executing a lambda in any of the threads that spin an event loop. For example:

dispatch_sync(dispatch_get_main_queue(), ^         


        
5条回答
  •  天命终不由人
    2020-11-22 05:53

    There are one new approach that is the easiest I think. It`s from Qt 5.4. Link to documentation

    void QTimer::singleShot(int msec, const QObject *context, Functor functor)
    

    Example:

    QTimer::singleShot(0, qApp, []()
    {
        qDebug() << "hi from event loop";
    });
    

    lambda will be executed in qApp thread(main thread). You could replace context with any QObject you want.

    Updated

    QTimer needs event loop to work. For Threads with no qt event loop(std::thread) we could create one. Code to run lambda in std::thread.

    QEventLoop loop;
    Q_UNUSED(loop)
    QTimer::singleShot(0, qApp, []()
    {
        qDebug() << "singleShot from std thread";
    });
    

    Full example

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    using std::thread;
    
    class TestObj
            :public QObject
    {
    // Used new connect syntax no need for Q_OBJECT define
    // you SHOULD use it. I used just to upload one file
    //Q_OBJECT
    public slots:
        void doWork()
        {
            qDebug() << "QThread id" << QThread::currentThreadId();
            QTimer::singleShot(0, qApp, []()
            {
                qDebug() << "singleShot from QThread" << QThread::currentThreadId();
            });
        }
    };
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        qDebug() << "main thread id" << QThread::currentThreadId();
    
        thread testThread([]()
        {
            QEventLoop loop;
            Q_UNUSED(loop)
            qDebug() << "std::thread id" << QThread::currentThreadId();
    
            QTimer::singleShot(0, qApp, []()
            {
                qDebug() << "singleShot from std thread" << QThread::currentThreadId();
            });
            qDebug() << "std::thread finished";
        });
        testThread.detach();
    
        QThread testQThread;
        TestObj testObj;
        testObj.moveToThread(&testQThread);
        QObject::connect(&testQThread, &QThread::started, &testObj, &TestObj::doWork);
        testQThread.start();
    
        return a.exec();
    }
    

提交回复
热议问题