qt线程工作者设计与阻塞while循环

时间:2013-09-13 21:35:14

标签: c++ multithreading qt opencv qtimer

我使用qt5和opencv创建一个使用qt为用户提供界面的应用程序,并在opencv中执行图像处理部分......

到目前为止,我的设计是:

  1. 我正在使用qt main gui thread
  2. 显示视频和一些标准控件,如按钮和复选框
  3. 用于捕获图像并处理它,我创建了一个派生自QObject的worker类并将其移动到一个线程....
  4. 在worker类(Worker :: process)中执行的函数有一个阻塞的while循环......它经常:
    • 从视频或相机中捕捉帧
    • 对其进行一些处理
    • 从cv :: Mat转换为QImage
    • 向主线程发出信号以显示QImage
  5. 也是为了接收用户输入,我正在使用从主线程到工作槽的发射信号
  6. 我遇到的问题是来自主线程的信号永远不会被工作人员挑选,因为循环时事件循环阻塞。

    经过大量搜索后,我想出了在将主线程信号连接到工作槽时使用Qt :: DirectConnection参数的解决方案。这解决了当时的问题。

    现在我需要在阻塞while循环中添加一个qtimer或qbasictimer ....并猜测是什么,定时器槽(在qtimer的情况下)和受保护的timerEvent处理程序(在qbasictimer的情况下)永远不会得到调用。我的预感是阻塞while循环再次成为罪魁祸首

    经过大量搜索和阅读论坛后,我得出的结论是,我的所有设计都可能不正确.....并且随着我不断向我的应用程序添加更多功能,这些问题将不断出现。

    我现在有两个选择:

    1. 以某种方式调用阻塞while循环中的线程exec()函数。所以向大师们提出的问题是: “我如何在worker QObject类中调用thread :: exec()方法,我需要引用运行worker的线程来调用exec()”(短期解决方案)

    2. 改变整个实施.....这里的问题是: “我的选择是什么......”(长期)

    3. 如果我的措辞或英语无论如何都不清楚,请随时询问详细信息.....谢谢......

1 个答案:

答案 0 :(得分:2)

在工作人员的阻止循环中,定期调用qApp->processEvents();

http://qt-project.org/doc/qt-5.1/qtcore/qcoreapplication.html#processEvents

#include <QApplication>
// ...
void Worker::doWork()
{
    while(true)
    {
        someLongImageProcessingFunction();
        qApp->processEvents();
    }
}

这应该允许处理插槽,以及更新计时器。

使用直接连接可以让您访问和更改工作人员的本地值,但是您应该注意线程安全。如果你将QMutexLocker放在由你的GUI修改的值之前,就在你的工作线程使用它们之前,那么你应该是好的。

http://qt-project.org/doc/qt-5.1/qtcore/qmutexlocker.html

此外,如果您希望在工作线程上运行任何这些插槽,则需要使用QueuedConnection

http://qt-project.org/doc/qt-5.1/qtcore/threads.html

http://qt-project.org/doc/qt-5.1/qtcore/qthread.html#details

在Qt文档的某些部分中,它描述了QThread类的子类化。其他部分推荐使用Worker / Producer模型,只需使用连接来设置如何使用线程。通常使用Worker / Producer模型的陷阱较少。

希望有所帮助。