我正在使用Qt5,QCoreApplication。 为了允许可读且易于维护的代码,我需要在类/线程A中编写一个阻塞方法,它将发出一个信号,连接到另一个线程B中的一个槽,然后等待一个答案或一个超时在线程B中异步发生 我首先考虑的是一种自然的解决方案:让线程B回复连接到线程A中的插槽的信号,然后以某种方式等待它。似乎QEventLoop可以为我做到这一点。但我一直在阅读相互矛盾的陈述:这就是模式,但如果你可以避免它:-)。 我很确定我可以通过阻止B在准备就绪时释放的0 QSemaphore来实现我的目的。代码可能不会那么复杂。 Qt开发人员认为你有什么经历? 有没有一个好的解决方案,或者你在我的描述中发现了一些有缺陷的分析症状(即你认为我永远不需要做那样的事情吗?: - ))?
答案 0 :(得分:2)
您可以利用的关键因素是Qt::BlockingQueuedConnection
。
此连接类型允许您从插槽传递返回值。您可以在信号插槽连接中使用它。您也可以直接调用插槽,而无需通过QMetaMethod::invoke
/ QMetaObject::invokeMethod
机制使用信号。
#include <QDebug>
#include <QThread>
#include <QCoreApplication>
class Master : public QObject {
Q_OBJECT
public:
Q_SIGNAL bool mySignal();
Q_SLOT void process() {
if (mySignal()) { // this can be a blocking call
qDebug() << "success!";
}
thread()->quit();
}
};
class Slave : public QObject {
Q_OBJECT
public:
Q_SLOT bool mySlot() {
// do whatever processing is needed here
// It's OK to call QCoreApplication::processEvents here
return true;
}
};
int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
QThread masterThread, slaveThread;
Master master;
Slave slave;
master.moveToThread(&masterThread);
slave.moveToThread(&slaveThread);
slave.connect(&master, SIGNAL(mySignal()), SLOT(mySlot()),
Qt::BlockingQueuedConnection);
masterThread.start();
slaveThread.start();
QMetaObject::invokeMethod(&master, "process");
masterThread.wait();
slaveThread.quit();
slaveThread.wait();
return 0;
}
#include "main.moc"
答案 1 :(得分:0)
如果你只是想在你的线程中发出一个信号,这意味着你的主线程将有一个插槽来连接线程信号,它很简单,只需发出它。 但是如果你想在你的线程中有一个插槽,并且在你的线程中接收信号等等,你必须在run方法中使用QEventloop。
通常,我只会使用QThread :: wait等待其他线程结束。这里要小心,有些Qt对象无法像QSql *和QTcpSocket那样在线程上工作....