I have a background thread performing a task and once done, UI should be updated. To update UI, I need the UI thread to execute my function which has the code to update UI.
Qt has QMetaObject::invokeMethod((QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr) method. According to documentation, Qt invokes a functor or a function in the thread that created the context pointer. But it can also be achieved using a lambda (as shown below).
// QtApplicationWrapper::sApp is of type QGuiApplication
// pFunc - pointer to a function
// pFuncParms - argument of type void *
QMetaObject::invokeMethod (QtApplicationWrapper::sApp,
[=] {
pFunc (pFuncParms);
},
Qt::QueuedConnection);
The above code works. But let's say I don't want to use a lambda or a functor.
pFunc could be directly passed to QMetaObject::invokeMethod as shown below:
QMetaObject::invokeMethod (QtApplicationWrapper::sApp,
pFunc,
Qt::QueuedConnection);
But I don't know how to pass arguments. The above code only works for a function taking no args.
How can I have pFunc invoked with its arguments in UI thread?
QMetaObject has multiple overloads, as documented at
https://doc.qt.io/qt-6/qmetaobject.html.One of those overloads is
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, Args &&... args), which takes an arbitrary number of arguments and may be called like this:QMetaObject::invokeMethod(this, "performAction", Qt::BlockingQueuedConnection, Q_ARG(std::string&, result), Q_ARG(std::string, action), Q_ARG(std::string, signal), Q_ARG(std::string, param));Please note that, when passing pointers or references, that you must either use a blocking connection or ensure some other way that the information you are passing is still valid when the message is actually executed.
The first two parameters are the most important piece information for this overload. The first one tells Qt, in which class to look for the function specified in the second parameter (which is a string, not a function pointer).
If you want to use 'proper notation', I strongly recommend using either a lambda or
std::bind.