Qt-使用线程 [英] Qt - Working with Threads
问题描述
我有一个QTimer,用于每20毫秒执行一次OpenCV代码和更改QLabel中的图像,但是我想更自然地运行此OpenCV代码,而不依赖于计时器.
相反,我想拥有一个处理用户输入的主线程和另一个使用OpenCV处理图像的线程,我找不到一种线程安全的方法来将一个线程中的QLabel图像(像素图)更改为另一个线程,有人可以描述这个过程,也许给出一些代码示例?我还想知道使用QThread的利弊,因为它是平台免费的,听起来像是用户级别的线程,而不是通常运行更流畅的系统级别.
您只能在应用程序的主(GUI)线程上实例化和使用QPixmap
(例如,QApplication::instance()->thread()
返回的内容)
这并不是说您不能在其他线程上使用QPainter和图形对象.大多数事情都可以正常运行,但例外情况是由操作系统施加的约束引导的.
Qt的成功版本设法找到了支持以前无法使用的功能的方法.例如:
- Qt 4.0添加了来自单独线程的渲染QImages
- Qt 4.4为在单独的线程中使用QPainter渲染为QGLWidget,QGLPixelBuffer和QGLFrameBufferObject
- Qt 4.4在何处引入了 QFontDatabase :: supportsThreadedFontRendering 以查看如果在GUI线程之外支持字体渲染,则在Qt5中,这是认为已过时并且总是返回是
注意:在Qt添加支持以在非GUI线程上使用QPixmap
的那一天,您不应该屏息.它们存在的原因是直接参与图形层.并找到一种解决方法,只是您可以使用名为QPixmap的东西对您没有任何好处,因为那时候您将使用与QBitmap
类似的东西. >
因此,所有与在另一个线程上实例化QFont
和QImage
之类的图形对象,并在QPainter
调用中使用它们来生成图形图像的能力有关.但是该图像不能直接绑定到显示器的活动部分上……您将始终被吸引到屏幕外的缓冲区中.它将必须安全地传递回主线程...这是所有直接到小部件的绘图和鼠标事件等必须通过的网关.
Qt的 Mandelbrot示例;我建议您开始使用它...确保您完全理解它.
注意:对于另一种旋转技巧,您可能有兴趣查看我的 Thinker-Qt 重新想象同一样本.
I have a QTimer for executing OpenCV code and changing an image in a QLabel every 20 milliseconds, but I want to run this OpenCV code more naturally and not depend on the timer.
Instead, I want to have one main thread that deals with user input and another thread that process images with OpenCV, what I can't find is a thread safe way to change the QLabel image (pixmap) in one thread from another thread, could someone describe this process, maybe give some code examples? I also want to know the pros and cons of using QThread, since it's plataform free, it sounds to be user level thread and not a system level which usually runs smoother.
You can only instantiate and work with QPixmap
on the main (GUI) thread of your application (e.g. what is returned by QApplication::instance()->thread()
)
That's not to say you can't work with a QPainter and graphics objects on other threads. Most things work, with exceptions guided by constraints imposed by the OS.
Successive versions of Qt have managed to find ways to support things that previously didn't work. For instance:
- Qt 4.0 added rendering QImages from separate threads
- Qt 4.4 added the ability to render text into images
- Qt 4.8 added the ability to use QPainter in a separate thread to render to a QGLWidget, QGLPixelBuffer and QGLFrameBufferObject
- Where Qt 4.4 introduced QFontDatabase::supportsThreadedFontRendering to check to see if font rendering was supported outside the GUI thread, in Qt5 this is considered obsolete and always returns true
Note: you shouldn't hold your breath for the day that Qt adds support to work with QPixmap
on non-GUI threads. The reason they exist is to engage the graphics layer directly; and finding a way to work around it just so you could use something named QPixmap wouldn't do any good, as at that point you'd just be using something equivalent to what already exists as QBitmap
.
So all that has to do with the ability to instantiate graphics objects like QFont
and QImage
on another thread, and use them in QPainter
calls to generate a graphical image. But that image can't be tied directly to an active part of the display...you'll always be drawing into some off-screen buffer. It will have to be safely passed back to the main thread...which is the gateway that all the direct-to-widget drawing and mouse events and such must pass through.
A well known example of how one might do this is Qt's Mandelbrot Sample; and I'd suggest getting started with that... making sure you understand it completely.
Note: For a different spin on technique, you might be interested to look at my Thinker-Qt re-imagining of that same sample.
这篇关于Qt-使用线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!