【问题标题】:Qt - Working with ThreadsQt - 使用线程
【发布时间】:2013-11-05 22:36:13
【问题描述】:

我有一个 QTimer 用于执行 OpenCV 代码并每 20 毫秒更改 QLabel 中的图像,但我想更自然地运行此 OpenCV 代码而不依赖于计时器。

相反,我希望有一个处理用户输入的主线程和另一个使用 OpenCV 处理图像的线程,我找不到一种线程安全的方法来从另一个线程中更改一个线程中的 QLabel 图像(像素图)线程,有人可以描述这个过程,也许给一些代码示例?我还想知道使用 QThread 的优缺点,因为它是免费的平台,听起来是用户级线程,而不是通常运行更流畅的系统级。

【问题讨论】:

  • 您可以将信号从工作线程发送到将更新标签内容的主线程。
  • @vahancho 你能给我一些例子或链接吗?
  • 如果我记得从一个单独的线程正确更新 UI,而不是在 Qt 下无法正常工作。不过,信号和槽是线程间通信的一种安全方式。
  • 使用 QThread 的一个很好的起点是阅读这篇文章:mayaposch.wordpress.com/2011/11/01/…

标签: c++ multithreading qt qthread qlabel


【解决方案1】:

您只能在应用程序的主 (GUI) 线程上实例化和使用 QPixmap(例如 QApplication::instance()->thread() 返回的内容)

这并不是说您不能在其他线程上使用 QPainter 和图形对象。大多数事情都有效,除了由操作系统施加的约束引导的例外情况。

Qt 的后续版本已经设法找到支持以前不起作用的东西的方法。例如:

注意:在 Qt 添加支持以在非 GUI 线程上使用 QPixmap 的那一天,您不应该屏住呼吸。它们存在的原因是直接参与图形层;并找到一种方法来解决它,以便您可以使用名为 QPixmap 的东西不会有任何好处,因为此时您只是使用与 QBitmap 已经存在的东西等效的东西。 p>

因此,所有这些都与在另一个线程上实例化 QFontQImage 等图形对象的能力有关,并在 QPainter 调用中使用它们来生成图形图像。但是该图像不能直接绑定到显示器的活动部分……您将始终在某些屏幕外缓冲区中进行绘制。它必须安全地传递回主线程...这是所有直接到小部件的绘图和鼠标事件等必须通过的网关。

Qt 的Mandelbrot Sample 就是一个众所周知的例子。我建议您开始使用...确保您完全理解它。

注意:对于不同的旋转技术,您可能有兴趣查看我对同一样本的Thinker-Qt 重新想象。

【讨论】:

  • 我会看看 Mandelbrot 样本,它看起来里面有我需要的一切,到目前为止,我可以看到答案在于发送更新信号......谢谢!
  • 查看 Mandelbrot 样本,他们将 Signal 声明为信号: void renderImage(const QImage &image, double scaleFactor); 'const' 有什么好处,为什么它是 &image 而不是 *image 作为函数通常是为指针参数定义的?
  • @mFeinstein 请记住,在信号/插槽设计中,一个信号可以连接到多个插槽。如果图像未声明为 const,那么如果有多个插槽运行怎么办?你最终会遇到这个修改的排序问题。 “最小特权原则”指导这种决定。至于为什么使用引用而不是指针,一个实际的区别是您说它是必需的并且永远不会为空。我自己只在 nullptr 是允许或预期的合法输入的地方使用原始指针。还有其他原因:研究“为什么使用引用”。
  • 我只是感到困惑,因为我从未见过这种函数签名。我见过的每个有指针作为输入的函数都会像 void foo(* input) 所以我不确定 void foo(&input) 是什么意思以及它的行为
  • @mFeinstein 正如我所说,研究参考是什么。它们是 C++ 的东西,不存在于 C 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多