我想知道在MainWindow的构造函数中创建但在以后移动到不同线程的两个QObject之间连接信号/插槽的最佳做法是什么...当我连接选项{{1}时,默认连接似乎不起作用事情开始工作......但有时信号/插槽失败......以下是我的代码模式..请告诉我是否需要更改我的课程设计......
MainWindow.cpp
Qt::Directconnection
ObjectA.h
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
{
myObjectA = new ObjectA;
myObjectB = new ObjectB;
connect( myObjectA,SIGNAL(signalA()),myObjectB,SLOT(slotB()) );
myObjectA.initiateProcess();
myObjectB.initiateProcess();
}
ObjectA.cpp
#include <QThread>
#include <QObject>
class ObjectA : public QObject
{
Q_OBJECT
public:
explicit ObbjectA(QObject *parent = 0);
void inititateProcess();
public slots:
void do_job();
signals:
void signalA();
private:
QThread *worker;
}
ObjectB.h
ObjectA::ObjectA(QObject* parent)
{
....
}
void ObjectA::do_jobA()
{
//do something;
}
void ObjectA::initiateProcess()
{
worker = new QThread;
connect(worker,SIGNAL(started()),this,SLOT(do_jobA()));
this->moveTo(worker);
worker->start()
}
ObjectB.cpp
#include <QThread>
#include <QObject>
class ObjectB : public QObject
{
Q_OBJECT
public:
explicit ObjectB(QObject *parent = 0);
void initiateProcess();
public slots:
void do_job();
void slotB();
signals:
void signalB();//for some other slot
private:
QThread *worker;
}
答案 0 :(得分:4)
一般来说,作为个人观点,即使在线程中,我也不会将阻塞代码(如QWaitCondition
)与事件循环混合,除非您知道它不会长时间阻塞。对于GUI线程,我会说“长”超过100毫秒(甚至在传统桌面应用程序中用户体验开始受到影响),但对于其他线程,它可能会更长,这取决于它可以阻止所有时间长度线程需要处理的事件和信号。
对于多个线程,通常最好对信号使用自动或显式排队的连接。直接连接将在发出信号的线程中执行,如果接收对象存在于另一个线程中,则插槽(以及因此,类中所有相关内容)需要成为线程安全的。更简单,更安全,不这样做,少跟踪一下。
如果您现在在一个线程中编写代码,但希望以后准备将其移动到其他线程,那么最好使连接排队。这样,单个线程的行为将基本相同,emit
将立即返回,之后您不会感到意外。
如果你想在任何线程中编写阻止未确定或其他时间过长的代码,最好继承QThread
,覆盖QThread::run()
并永远不要在其中调用exec()
。然后你可以在你自己的循环中使用QMutex和QWaitCondition,或者使用其他一些“传统的”线程间通信方法。您仍然可以从线程发出信号,但连接应排队以避免线程问题。还要记住,添加到QThread的任何插槽都应该在QThread对象所在的线程中执行,而不是执行run()
方法的线程。这实际上是非常方便的模式,你可以在QThread子类的插槽中“隐藏”所有实际的线程交互代码(记住,它们不会在run()
运行的线程中执行),只要你不注意锁定这些中使用的任何QMutex
时间过长。
答案 1 :(得分:1)
根据您的评论,您的主题正忙于QWaitCondition
,因此它无法处理信号。如果您确实需要QWaitCondition
,则可以使用QCoreApplication::processEvents
和超时对插槽进行轮询,例如
while(true) {
if(condition.wait(&mutex, 1000)) {
// process condition
} else {
QCoreApplication::processEvents()
}
}
但这涉及处理信号的延迟(在本例中为1秒)。除此之外,还有类似的question on SO
建议摆脱QWaitCondition
并使用信号/插槽。