我有以下代码:
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;
}
来自doSomething
的问题必须通过QMetaObject::invokeMethod
进行调用。我知道连接类型有一些东西。 是否有人可以解释引擎盖下的内容?
答案 0 :(得分:23)
由于您没有指定Qt::ConnectionType
,因此该方法将被调用为Qt::AutoConnection
,这意味着如果对象的线程亲和性是,则将同步调用它(如正常函数调用)当前线程,否则为异步。 “异步”表示构造QEvent
并将其推送到消息队列,并在事件循环到达时处理。
如果收件人对象可能位于另一个线程中,则使用QMetaObject::invokeMethod
的原因是,尝试直接在另一个线程中的对象上调用插槽可能会导致损坏,如果它访问或修改非线程,则会导致更糟糕的情况安全数据。
答案 1 :(得分:20)
我喜欢这个技巧:
void A:doSomethingSlot()
{
if (thread()!=QThread::currentThread()) {
QMetaObject::invokeMethod(this,"doSomethingSlot", Qt::QueuedConnection);
return;
}
// this is done always in same thread
...
emit ready();
}