假设我有一个包含 SLOT listen()
的 class cWorker : public QObject
。这个对象被移动到一个单独的线程。
主窗口包含一个 class GLWidget : public QGLWidget
,它有一个 SIGNAL request()
如何在两个线程之间连接
信号槽?它应该是直截了当的,但我找不到任何示例代码。谢谢。
int main(int argc, char *argv[])
{
cWorker* worker = new cWorker();
QThread* thread = new QThread;
worker->moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(work()) );
thread->start();
QApplication a(argc, argv);
MainWindow w;
GLWidget *my_gl_widget = w.findChild<GLWidget*>("widget");
// THIS DOESN'T WORK
QObject::connect(my_gl_widget, SIGNAL( request() ), worker, SLOT( listen() ));
w.show();
return a.exec();
最佳答案
当您连接不同线程中的两个QObject
时,Qt
总是使用QueuedConnection
。这意味着当发出信号时,Qt
会向另一个对象发送一个事件。 More info .
问题是 Qt
在您退出循环之前无法传递事件。
为了能够处理事件,您需要 a) 打破 cWorker::work
中的无限循环
或 b) 在那里调用 processEvents
.
a) 要打破循环,您可以使用 QTimer
。所以不是:
while (true) do something;
您将拥有:
void onTimer()
{
do something()
}
b) 如果你需要在那里执行持久化操作(计算等)你可以使用QCoreApplication::processEvents .
这是来自 documentation 的 processEvents
的描述:
Processes pending events for the calling thread for maxtime milliseconds or until there are no more events to process, whichever is shorter. You can call this function occasionally when you program is busy doing a long operation (e.g. copying a file).
结论:
无限循环是您出现问题的原因。您可以确保:如果删除此行,将调用插槽 listen
:
QObject::connect(thread, SIGNAL(started()), worker, SLOT(work()) );
关于c++ - 跨线程的信号槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26522062/