Зачем использовать QMetaObject:: invokeMethod при выполнении метода из потока
у меня есть следующий код:
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
. Я знаю, что есть что-то с типом подключения. может ли кто-нибудь объяснить, что находится под капотом?
2 ответов
как вы не указали Qt::ConnectionType
метод будет вызван как Qt::AutoConnection
, что означает, что он будет вызываться синхронно (как обычный вызов функции), если сродство потока объекта к текущему потоку и асинхронно в противном случае. "Асинхронный" означает, что QEvent
строится и помещается в очередь сообщений и будет обрабатываться, когда цикл событий достигнет его.
причина использовать QMetaObject::invokeMethod
если объект получателя может быть в другом потоке попытка вызова слота непосредственно на объекте в другом потоке может привести к повреждению или хуже, если он обращается к или изменяет данные, не являющиеся потокобезопасными.
Мне нравится этот прием:
void A:doSomethingSlot()
{
if (thread()!=QThread::currentThread()) {
QMetaObject::invokeMethod(this,"doSomethingSlot", Qt::QueuedConnection);
return;
}
// this is done always in same thread
...
emit ready();
}