如何在Qt,gcd样式的给定线程中执行函子或lambda?

如何在Qt,gcd样式的给定线程中执行函子或lambda?

在使用GCD的objc中,有一种在旋转事件循环的线程中执行lambda的方法。例如:

dispatch_sync(dispatch_get_main_queue(), ^{ /* do sth */ });

或:

dispatch_async(dispatch_get_main_queue(), ^{ /* do sth */ });

它执行一些东西(相当于[]{ /* do sth */ }在主线程的队列中,无论是阻塞还是异步。

我怎么能在Qt中做同样的事情呢?

根据我所读到的,我想解决办法是以某种方式向主线程的某个对象发送一个信号。但什么目标?只是QApplication::instance()?(这是唯一存在于主线程中的对象。)什么信号?


从目前的答案和我目前的研究来看,我确实需要一些虚拟对象来坐在主线程中,其中有一些插槽,只是等待进入一些代码来执行。

所以,我决定把QApplication再加一句。我当前的代码不起作用(但也许你可以帮上忙):

#include <QApplication>#include <QThread>#include <QMetaMethod>#include <functional>#include <assert.h>class App : public QApplication{
    Q_OBJECTpublic:
    App();signals:public slots:
    void genericExec(std::function<void(void)> func) {
        func();
    }private:
    // cache this
    QMetaMethod genericExec_method;public:
    void invokeGenericExec(std::function<void(void)> func, Qt::ConnectionType connType) {
        if(!genericExec_method) {
            QByteArray normalizedSignature = QMetaObject::normalizedSignature("genericExec(std::function<void(void)>)");
            int methodIndex = this->metaObject()->indexOfSlot(normalizedSignature);
            assert(methodIndex >= 0);
            genericExec_method = this->metaObject()->method(methodIndex);
        }
        genericExec_method.invoke(this, connType, Q_ARG(std::function<void(void)>, func));
    }};static inlinevoid execInMainThread_sync(std::function<void(void)> func) {
    if(qApp->thread() == QThread::currentThread())
        func();
    else {
        ((App*) qApp)->invokeGenericExec(func, Qt::BlockingQueuedConnection);
    }}static inlinevoid execInMainThread_async(std::function<void(void)> func) {
    ((App*) qApp)->invokeGenericExec(func, Qt::QueuedConnection);}


蝴蝶不菲
浏览 544回答 3
3回答

鸿蒙传说

这样的东西会有用吗?template&nbsp;<typename&nbsp;Func>inline&nbsp;static&nbsp;void&nbsp;MyRunLater(Func&nbsp;func)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;QTimer&nbsp;*t&nbsp;=&nbsp;new&nbsp;QTimer(); &nbsp;&nbsp;&nbsp;&nbsp;t->moveToThread(qApp->thread()); &nbsp;&nbsp;&nbsp;&nbsp;t->setSingleShot(true); &nbsp;&nbsp;&nbsp;&nbsp;QObject::connect(t,&nbsp;&QTimer::timeout,&nbsp;[=]()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t->deleteLater(); &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;QMetaObject::invokeMethod(t,&nbsp;"start",&nbsp;Qt::QueuedConnection,&nbsp;Q_ARG(int,&nbsp;0));}这段代码将使您的lambda尽可能快地在主线程事件循环上运行。不支持args,这是一个非常基本的代码。注意:我没有正确地测试它。
打开App,查看更多内容
随时随地看视频慕课网APP