I have a background thread and the thread calls some methods that update the UI (in order to show progress bars and show additional info in text areas).
If I modify some UI widget values, a “Cannot send events to objects owned by a different thread” assertion error is raised.
Looking at forums, I read that I could use QMetaObject::invokeMethod method but it just works if I pass it the Qt::DirectConnection flag that actually raises the same error shown above.
If I use Qt::QueuedConnection or Qt::AutoConnection, the invokeMethod returns false.
My code looks similar to this:
.h:
class A : public QMainWindow
{
Q_OBJECT
QProgressBar* pb;
public slots:
bool m(bool, int);
};
class B
{
A* a;
public:
void handleEvent();
};
.cpp:
bool A::m(bool x, int y)
{
pb->setValue(y);
return x;
}
void B::handleEvent()
{
//a->m(true, 12); //raises an assertion error
bool r;
//bool ret = QMetaObject::invokeMethod(a, "m", Qt::DirectConnection, Q_RETURN_ARG(bool, r), Q_ARG(bool, true), Q_ARG(int, 12)); //raises the same assertion error error
bool ret = QMetaObject::invokeMethod(a, "m", Qt::AutoConnection, Q_RETURN_ARG(bool, r), Q_ARG(bool, true), Q_ARG(int, 12)); //is ignored and ret contains false.
}
Do you know what is going on or what i am doing wrong? or maybe, can someone suggest me another approach to deal with my newbie problem?
Thanks in advance,
Ernesto
I haven’t used
invokeMethod()myself, but to do this, I usually just use signals and slots. For instance, you could create a signal as a member ofclass Bthat is connected to the slot inclass Athat updates the progress:A::m()will have to return void in this case but that is not a problem because when using a queued connection, you cannot get a return value anyway since the call is asynchronous (emit update_signal(true,12)may return before the slot function is called making it impossible to have a return value ready).You can actually perform this connection anywhere as long as you have pointers to an object of type
Aand an object of typeB. This makes the signals and slots very flexible since you could completely decoupleAfromB, yet still allow them to communicate through signals and slots. For instance:In this case,
bdoes not have to store a pointer or know anything aboutayet they can communicate through a thin well-defined channel.