В моем приложении есть основной поток и рабочий поток (QThread
).
Из основного потока я бы хотел вызвать метод моего рабочего потока и запустить его в контексте потока.
Я пытался использовать QMetaObject::invokeMethod
и дать ему опцию QueuedConnection
, но она не работает.
Я также попытался передать сигналы из основного потока (который подключен к слоту рабочего потока), но это также не удалось.
Вот пример примерно того, что я пробовал:
class Worker : public QThread
{
Q_OBJECT
public:
Worker() { }
void run()
{
qDebug() << "new thread id " << QThread::currentThreadId();
exec();
}
public slots:
void doWork()
{
qDebug() << "executing thread id - " << QThread::currentThreadId();
}
};
Используя способ QMetaObject:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id - " << QThread::currentThreadId();
Worker worker;
worker.start();
QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
return a.exec();
}
Использование сигнального пути:
class Dummy : public QObject
{
Q_OBJECT
public:
Dummy() { }
public slots:
void askWork() { emit work(); }
signals:
void work();
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main thread id - " << QThread::currentThreadId();
Worker worker;
worker.start();
Dummy dummy;
QObject::connect(&dummy, SIGNAL(work()), &worker, SLOT(doWork()), Qt::QueuedConnection);
QTimer::singleShot(1000, &dummy, SLOT(askWork()));
return a.exec();
}
В обоих случаях идентификатор основного потока будет напечатан в QThread
doWork
.
Кроме того, я подумал о реализации простого производителя-потребителя, но если это работает, есть ли какая-то причина, почему бы не сделать это таким образом?