为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
蝴蝶不菲 2019-06-24 13:07:21
如何在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);}
查看完整描述

3 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

这样的东西会有用吗?

template <typename Func>inline static void MyRunLater(Func func) {
    QTimer *t = new QTimer();
    t->moveToThread(qApp->thread());
    t->setSingleShot(true);
    QObject::connect(t, &QTimer::timeout, [=]() {
        func();
        t->deleteLater();
    });
    QMetaObject::invokeMethod(t, "start", Qt::QueuedConnection, Q_ARG(int, 0));}

这段代码将使您的lambda尽可能快地在主线程事件循环上运行。不支持args,这是一个非常基本的代码。

注意:我没有正确地测试它。


查看完整回答
反对 回复 2019-06-24
  • 3 回答
  • 0 关注
  • 543 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信