Invoke slot asynchronously without connecting to it using clear line of code

前端 未结 1 1181
闹比i
闹比i 2021-01-23 15:33

I have encountered quite freaky bug - QAction::trigger caused blocking dialog to appear, which caused my server which called trigger to go stuck (eg. n

相关标签:
1条回答
  • 2021-01-23 16:04

    You can separate that into a function QueuedInvoke like this:

    //overload for methods/slots
    //the slot gets invoked in the thread where the QObject lives
    template <typename Object, typename T>
    void QueuedInvoke(Object* object, T (Object::* f)()){
        QObject signalSource;
        QObject::connect(&signalSource, &QObject::destroyed,
                         object, f, Qt::QueuedConnection);
    }
    //overload for functors
    //the functor gets invoked in the thread where the contextObject lives
    //or in the current thread if no contextObject is provided
    template <typename Func>
    void QueuedInvoke(Func&& f, QObject* contextObject = QAbstractEventDispatcher::instance()){
        QObject signalSource;
        QObject::connect(&signalSource, &QObject::destroyed, 
                         contextObject, std::forward<Func>(f), Qt::QueuedConnection);
    }
    

    This will leverage the destroyed() signal emitted from the temporary QObject to post a queued event into the event loop. The slot/functor is actually invoked when the event loop processes that event.

    So, Instead of the 3 lines you posted, You can use the above function like this:

    QueuedInvoke(targetAction_.data(), &QAction::trigger);
    

    My answer is based on this great answer about executing a functor in a given QThread. You can refer to it for more details.

    0 讨论(0)
提交回复
热议问题