问题
我目前正在把保险丝和qt5放在一起。在Qt和FUSE之间还没有桥梁,FUSE主线程(它正在生成其他工作的FUSE线程)和QCoreApplication只是并行运行。
但我希望能够在基于QObject的对象和线程的Read(.)之间发送和接收数据在使用Qt信号和插槽中显示的函数。
问题
现在我要修改(.)函数从基于QObject的类中使用Qt的信号和槽来检索数据。从线程发送信号是可行的,但是如果没有显式的QEventLoop,我就无法接收到答复。因此,我查看了1中的代码,它在设计上非常出色,但我还没有让它正常工作。
伪码(摘自1):
QNetworkAccessManager qnam;
QNetworkReply *reply = qnam.get(QNetworkRequest(QUrl(...)));
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
/* reply has finished, use it */看起来很有趣,我所需要的只是一个类似于处理请求的QObject派生类。
当我处理该代码时,我遇到的问题是,我的QNetworkReply实现不会等待loop.exec()运行,然后循环就不会接收已完成的()信号。
但是,难道没有比产生一个QEventLoop更容易的东西吗?
注意:示例1中的 QNetworkReply和QNetworkAccessManager是在线程中生成的,但是,我需要能够使用信号和插槽与QCoreApplication的偶数队列进行通信,因为包含数据的对象来自不同的QThread (在这里可以是QCoreApplication或特殊的QThread)。
使用Qt::QueuedConnection
我还找到了两个,也许:
连接(src,信号(信号-签名),dest,时隙(时隙-签名),Qt::QueuedConnection);
我只想要但我怀疑。
链接
发布于 2013-10-17 14:06:49
你可能要面对的是QNetworkAccessManager 内部使用线程处理http请求。。这就是为什么它“不等待”你。要修复它,需要进行相当简单的修改:
QNetworkAccessManager qnam;
QEventLoop loop;
QNetworkReply *reply = qnam.get(QNetworkRequest(QUrl(...)));
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
if (!reply->isFinished()) loop.exec();在多线程中使用QObjects时要注意的事项
当作为信号源的对象存在(在其中实例化)一个与带有槽的对象的线程不同的线程时,连接将自动为QueuedConnection类型。
真正的问题是:每个QObject都有一个线程关联。默认的关联是对象实例化的线程。您不应该直接从其他线程使用这样的对象。
您可能要做的是在同一个线程中实例化发送方和接收方对象,然后从另一个线程发出信号。这是潜在错误的来源,如果这样的对象的用户强制进行非自动的直接连接,则会导致未定义的行为。
无论何时执行emit object->signal(...),以下不变量都应该保持:
Q_ASSERT(QThread::currentThread() == object->thread());可以在您显式执行的每个emit()前面添加这些不变的检查。
如果断言失败,则需要使用QObject::moveToThread将对象移动到要触发其信号的线程。您可以通过从运行在QThread中的代码调用QThread::currentThread()来获得给定pthread的QThread::currentThread()。QThread的一个实例将自动为您创建:)
发布于 2013-10-17 12:49:13
是的,您需要Qt::QueuedConnection方法。但也要确保您正在使用多线程Qt库。IIRC这是一个构建时选项。
另见:Qt文档
https://stackoverflow.com/questions/19426900
复制相似问题