-1

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

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

  1. 我正在使用 qt 主 gui 线程显示视频和一些标准控件,例如按钮和复选框
  2. 为了捕获图像并对其进行处理,我创建了一个从 QObject 派生的工作类并将其移至线程......
  3. 在工作类(Worker::process)中执行的函数有一个阻塞的while循环......不断地:
    • 从视频或相机中捕获帧
    • 对其进行一些处理
    • 从 cv::Mat 转换为 QImage
    • 向主线程发出信号以显示 QImage
  4. 同样为了接收用户输入,我正在使用从主线程向工作槽发送信号

我面临的问题是,由于事件循环阻塞了while循环,因此来自主线程的信号从未被工作人员拾取。

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

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

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

我现在有两个选择:

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

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

请随时询问详细信息,以防我的措辞或英语以任何方式使问题不清楚......谢谢......

4

1 回答 1

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 模型,并且只使用连接来设置你如何使用你的线程。通常,工人/生产者模型的陷阱较少。

希望有帮助。

于 2013-09-13T23:05:43.783 回答