Multithreading 在非GUI线程中持续更新QLabel
我在另一个线程中访问QtGUI的QLabel的QPixmap,因为我最终将使用它在QLabel中显示mjpeg流,我决定使用QLabel,因为它是最简单的方法Multithreading 在非GUI线程中持续更新QLabel,multithreading,qt,pyqt,qlabel,Multithreading,Qt,Pyqt,Qlabel,我在另一个线程中访问QtGUI的QLabel的QPixmap,因为我最终将使用它在QLabel中显示mjpeg流,我决定使用QLabel,因为它是最简单的方法 它应该看起来像“活动”的,并且不会阻塞UI,从而使用另一个(非gui)线程 QLabel中没有显示任何内容。只有例外情况QPixmap:在GUI线程之外使用pixmap是不安全的 有更好或正确的方法吗? 这是我的另一个线程的PyQt代码:self.theQlabel.setPixmap(QtGui.QPixmap.fromImage(my
它应该看起来像“活动”的,并且不会阻塞UI,从而使用另一个(非gui)线程 QLabel中没有显示任何内容。只有例外情况
QPixmap:在GUI线程之外使用pixmap是不安全的
有更好或正确的方法吗?
这是我的另一个线程的PyQt代码:
self.theQlabel.setPixmap(QtGui.QPixmap.fromImage(myQimg)
而不是直接设置pixmap,让外部线程发出一个updatePixmap
信号。然后在GUI线程中,监听该信号并在那时更新pixamp。类似的东西应该可以工作(在C++中):
不要直接设置pixmap,而是让外部线程发出一个
updatePixmap
信号。然后在GUI线程中,监听该信号并在此时更新pixmap。类似的方法应该可以工作(在C++中):
我认为在GUI线程以外的任何东西中创建一个<代码> qPixMAP可能是危险的。在主线程中,您可能需要考虑传递<代码> QImage < /代码>,并将其转换为<代码> QPIXMAP> <代码>。我找不到直接引用来支持这个断言,但
暗示 所有小部件和几个相关类,例如QPixmap,都不能在辅助线程中工作 电子邮件线程位于也似乎同意我的观点。
< P>我认为,即使在GUI线程之外的任何东西中创建一个<代码> qPixMAP>/代码>可能是危险的。您可能需要考虑通过< <代码> QImage <代码>,并将其转换为主线程中的<代码> QPIXMAP> <代码>。我找不到直接引用来支持这个断言,但 暗示 所有小部件和几个相关类,例如QPixmap,都不能在辅助线程中工作 电子邮件线程位于似乎也同意我的观点。在这个QLabel的winId()中创建原始DirectX/OpenGL操作系统上下文,然后做任何你想做的事情。我认为,这是高性能高清视频的最佳方式,也是唯一的方式:)有时,您只需要使用原始的东西来实现最大的性能,并触摸计算机中的熨斗:)在这个QLabel的winId()中创建原始DirectX/OpenGL操作系统上下文,然后做任何您想做的事情。我认为,这是高性能高清视频的最佳方式,也是唯一的方式:)有时候你只需要使用原始的东西来获得最高的性能,并触及计算机中的铁:)在连续(流)场景中,Gui线程将在
updatePixmap
的插槽中忙碌,有效地使它没有反应。是吗?从非GUI线程更新GUI是不可能的,而且极有可能导致各种问题和崩溃。除非将连接调用更改为使用Qt::QueuedConnection,否则此处给出的解决方案将不起作用。Qt::QueuedConnection将跨越线程边界并从GUI线程内执行插槽。@vijboy,我假设耗时的操作是构建QPixmap,这是在外部线程中完成的。将此pixmap分配给标签不会花费太长时间。@Laurent,绝对如此。我现在就试试这个。但无论如何,对GUI元素的线程安全访问应该是任何现代图形库的一项功能,不是吗……在连续(流)场景中,GUI线程将在updatePixmap
的插槽中忙碌,从而使其无响应。是吗?从非GUI线程更新GUI是不可能的,而且极有可能导致各种问题和崩溃。除非将连接调用更改为使用Qt::QueuedConnection,否则此处给出的解决方案将不起作用。Qt::QueuedConnection将跨越线程边界并从GUI线程内执行插槽。@vijboy,我假设耗时的操作是构建QPixmap,这是在外部线程中完成的。将此pixmap分配给标签不会花费太长时间。@Laurent,绝对如此。我现在就试试这个。但是无论如何,对GUI元素的线程安全访问应该是任何现代图形库的一项功能,不是吗…在主线程中以30 FPS的速度将QImage
转换为QPixmap
,用于显示高清图像。我对加载用于视频目的的主线程感到很糟糕。有什么标准的做法吗?感谢您特别指出,使显示依赖于QPixmap
外部gui/主线程是问题的根源,包括crashes@vijiboy问题是“转换”过程可能涉及更新OpenGL纹理(如果您使用的是适当的渲染器)。所以我感觉到了你的痛苦,但总的来说,我不知道有什么办法可以解决这个问题。请让我知道你是否明白了:-)。以30 FPS的速度将QImage
转换为QPixmap
,只用于显示主线程中的高清图像。我对加载用于视频目的的主线程感到很糟糕。有什么标准的做法吗?感谢您特别指出,使显示依赖于QPixmap
外部gui/主线程是问题的根源,包括crashes@vijiboy问题是“转换”过程可能涉及更新OpenGL纹理(如果您使用的是适当的渲染器)。所以我感觉到了你的痛苦,但总的来说,我不知道有什么办法可以解决这个问题。请让我知道,如果你找到它:-)。
// In the GUI thread:
class YourWidget: QObject {
public:
YourWidget();
public slots:
void updatePixmap(const QPixmap& pixmap);
}
YourWidget::YourWidget() {
// Connect to the signal here:
QObject::connect(otherThread, SIGNAL(updatePixmap(const QPixmap&)), this, SLOT(updatePixmap(const QPixmap&)));
}
YourWidget::void updatePixmap(const QPixmap& pixmap) {
// Update the pixmap here in a thread-safe way
}
// In the external thread:
// Emit the signal. The GUI thread will receive it and can then update the pixmap
emit updatePixmap(thePixmap);