【问题标题】:Signal-Slot across threads跨线程的信号槽
【发布时间】:2014-12-18 18:22:04
【问题描述】:

假设我有一个包含SLOT listen()class cWorker : public QObject。这个对象被移动到一个单独的线程。

主窗口包含一个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();

}

【问题讨论】:

  • 你怎么知道它不起作用? connect 返回什么?它输出什么错误?你检查my_gl_widget 不为空吗?
  • 为什么在MainWindow 中没有一个返回GLWidget 的函数?在这种情况下使用QObject::findChild 是愚蠢的。
  • 它编译并运行,插槽永远不会被执行。
  • 回答我的其他三个问题和thuga的问题。
  • 我只是在插槽中放了一个 cout。

标签: c++ multithreading qt


【解决方案1】:

当你在不同的线程中连接两个QObjects 时,Qt 总是使用QueuedConnection。这意味着当发出信号时Qt 将事件发送到另一个对象。 More info.

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

为了能够处理事件,您需要 a) 在 cWorker::work 中破坏您的 infinite loop 或 b) 在那里调用 processEvents

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

while (true) do something;

你将拥有:

void onTimer()
{
 do something()
}

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

这里是来自documentationprocessEvents 的描述:

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

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

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

【讨论】:

  • 确实如此。谢谢。这是我的问题:我正在运行主线程以最大 60Hz 渲染 glwindow,而工作线程以 1kHz 渲染。工作线程包含顶点数据并持续对其进行操作。 paintGL() 中需要顶点数据。每当调用paintGL()时,将顶点数据从工作线程复制/传递到主线程的最佳方法是什么?我认为信号槽机制是最好的,但现在似乎不是这样?
  • 只是为了确保我理解正确:我应该把processEvents 放在我的无限while循环中吗?如果复制顶点数据的时间超过maxtime,会发生什么情况?似乎应该有更好的方法在连续运行的线程之间交换数据..
  • 在大多数情况下,只有在发送少量数据或交付时间不重要时才需要使用信号槽。但是,如果它对您有用,那么可以,您只需将 processEvents 添加到循环中。使用另一个重载方法processEvents,它不需要maxtime
  • 我也会考虑共享数据和QMutex。您也可能想阅读qt-project.org/forums/viewthread/6276qt-project.org/forums/viewthread/31125
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 2020-04-30
  • 2015-08-21
  • 1970-01-01
相关资源
最近更新 更多