问题
I have following code:
class A : public QObject
{
Q_OBJECT
public:
A() : QObject()
{
moveToThread(&t);
t.start();
}
~A()
{
t.quit();
t.wait();
}
void doSomething()
{
QMetaObject::invokeMethod(this,"doSomethingSlot");
}
public slots:
void doSomethingSlot()
{
//do something
emit ready();
}
signals:
void ready();
private:
QThread t;
}
The question why from doSomething
it must be call via QMetaObject::invokeMethod
. I know that there is something with connection type. Could some one explain what is under the hood?
回答1:
As you haven't specified a Qt::ConnectionType
, the method will be invoked as Qt::AutoConnection
, which means that it will be invoked synchronously (like a normal function call) if the object's thread affinity is to the current thread, and asynchronously otherwise. "Asynchronously" means that a QEvent
is constructed and pushed onto the message queue, and will be processed when the event loop reaches it.
The reason to use QMetaObject::invokeMethod
if the recipient object might be in another thread is that attempting to call a slot directly on an object in another thread can lead to corruption or worse if it accesses or modifies non-thread-safe data.
回答2:
I like this trick:
void A:doSomethingSlot()
{
if (thread()!=QThread::currentThread()) {
QMetaObject::invokeMethod(this,"doSomethingSlot", Qt::QueuedConnection);
return;
}
// this is done always in same thread
...
emit ready();
}
来源:https://stackoverflow.com/questions/13948337/why-using-qmetaobjectinvokemethod-when-executing-method-from-thread