我想知道如何告诉QObject处理所有信号并调用与它们相关的插槽。下面是我遇到的具体问题,为了更好地描述这个问题:
我的程序由三个qthread组成:Main, Communication and Input。
通信线程通过网络处理通信,输入线程处理用户输入,两者都有几个信号槽连接到主线程。无论何时发生网络事件,或者无论何时用户输入命令行命令,都会调用来自相应线程的信号,然后激活主线程中相应的连接槽。主线程的作用是处理这些事件。我的代码如下所示:
QApplication a(argc, argv);
CommObj co; //inherits from QThread
co.start(); //Starts the thread
InputObj io; //inherits from QThread
io.start(); //Starts the thread
MainObj u(&co,&io);
return a.exec();
现在,我想要实现的是主线程不到达最后一行。我的意图是在MainObj的构造函数中调用一个方法run(),它将沿着下面的行做一些事情:
void run ()
{
forever
{
//process all signals..
}
}
但是,我不知道如何实现进程的所有信号部分。任何关于如何做到这一点的建议(包括变通方法)将是非常欢迎的。
这完全没有必要。a.exec()
运行一个事件循环,接收和处理其他线程发送的事件。
当一个slot被调用时,由于一个信号在另一个线程中被发出,Qt将发送一个QMetaCallEvent
给接收对象。QObject::event
方法能够根据事件中的数据重新合成槽位调用。
因此,您不需要做任何事情。a.exec()
做你想做的。您可以随意地从MainObj
的构造函数中调用它,如qApp->exec()
或QEventLoop loop; loop.exec()
,但这是相当糟糕的设计。
真正的问题是:
-
为什么需要
MainObj
的构造函数来旋转事件循环? -
你在
io
中处理什么样的"用户输入"?你不能从这个线程访问任何GUI对象。 -
如果你使用Qt的网络,为什么你从
QThread
派生?您肯定不想这样做-除非您旋转事件循环,否则它将无法工作,因此您不妨只使用不进行更改的QThread
。为了安全起见,你只需要将线程设置为可破坏的,所以:
无论如何,通过不使用旋转事件循环的标准class Thread { using QThread::run; // make it final public: Thread(QObject * parent = 0) : QThread(parent) {} ~Thread() { requestInterruption(); quit(); wait(); } };
QThread
,通信将是单向的。
您需要按照如下方式重新架构:
-
如上所述使用
Thread
类。随时销毁是安全的 -
让worker对象使用信号/插槽/定时器异步运行。
您需要的是processEvents
函数。例如,如果您不希望用户能够与小部件交互,但您希望图形更新,则使用
processEvents(QEventLoop::ExcludeUserInputEvents);
详情请参阅文档