跨线程的信号槽

时间:2014-10-23 05:54:56

标签: c++ multithreading qt

假设我的class cWorker : public QObject包含SLOT listen()。此对象将移至单独的线程。

主窗口包含class GLWidget : public QGLWidget,其中包含SIGNAL request()

我如何connect跨两个线程的信号槽?它应该是直截了当但我找不到任何示例代码。感谢。

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();

}

1 个答案:

答案 0 :(得分:6)

当您在不同的帖子中连接两个QObject时,Qt始终使用QueuedConnection。这意味着当发出信号时Qt将事件发送到另一个对象。 More info

问题是Qt在退出循环之前无法传递事件。

为了能够处理您需要的事件a)打破infinite loop中的cWorker::work或b)打电话processEvents

a)要打破循环,您可以使用QTimer。所以而不是:

while (true) do something;

你将拥有:

void onTimer()
{
 do something()
}

b)如果你需要在那里执行持久性操作(计算等),你可以使用QCoreApplication::processEvents

以下是documentation中的processEvents的说明:

  

处理调用线程的挂起事件maxtime毫秒或直到没有更多事件要处理,以较短者为准。   当程序忙于长时间操作(例如复制文件)时,您可以偶尔调用此功能。

<强>结论:
无限循环是你问题的原因。您可以确保:如果删除此行,将调用插槽listen

  

QObject :: connect(thread,SIGNAL(started()),worker,SLOT(work()));