2012-01-02 76 views
0

我访问Qt的图形用户界面的QLabel的QPixmap的另一个线程因为我将最终使用的QLabel显示MJPEG流,我决定,请使用QLabel,因为它最简单的方法
它应该看起来像'Live',并且不会因为使用另一个(非gui)线程而阻塞UI。更新QLabel在非GUI线程连续

在QLabel中什么也没有显示。只有例外QPixmap: It is not safe to use pixmaps outside the GUI thread
任何更好或正确的方法来做到这一点?
这里是另一个线程我的PyQt代码:self.theQlabel.setPixmap(QtGui.QPixmap.fromImage(myQimg)

回答

1

而不是直接设置的像素图,使外螺纹发出updatePixmap信号。然后在GUI线程中,听取信号并在那个时候更新pixamp。这样的东西应该工作(在C++):

// 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); 
+0

连续(流媒体)情况下,Gui线程将在'updatePixmap'的插槽内忙碌,从而使其无响应。会是这样吗? – vijiboy 2012-01-02 14:50:39

+2

从非GUI线程更新GUI是不可能的,并且很可能导致各种问题和崩溃。此处给出的解决方案将不起作用,除非连接调用更改为使用Qt :: QueuedConnection,它将跨越线程边界并从GUI线程内执行插槽。 – Chris 2012-01-02 15:48:39

+1

@vijboy,我假设耗时的操作是构建QPixmap,并且这是在外部线程中完成的。将这个像素图分配给标签不应该花很长时间。 – 2012-01-03 04:12:21

2

我认为这可能是危险的,甚至比GUI线程以外的任何创造一个QPixmap。您可能需要考虑在主线程中传递QImage并将其转换为QPixmap。我找不到一个直接引用来支持这种说法,但

http://developer.qt.nokia.com/doc/qt-4.8/thread-basics.html

暗示,

所有部件和几个相关的课程,比如,QPixmap,不要在辅助线程工作。

电子邮件线程

http://lists.trolltech.com/qt-interest/2008-11/msg00534.html

似乎也同意我。

+0

在30 FPS为主图像中的高清图像将'QImage'转换为'QPixmap'仅用于显示。加载视频主线程让我感觉不好。是否有任何标准做法...? – vijiboy 2012-02-21 16:20:48

+0

感谢您特别指出,制作显示依赖'QPixmap'外侧gui /主线程是问题的来源,包括崩溃 – vijiboy 2012-02-21 16:23:11

+0

@vijiboy问题是,“转换”过程可能涉及说,更新OpenGL纹理(如果你'重新使用适当的渲染器)。所以我觉得你的痛苦,但不知道一般的方式来解决这个问题。请让我知道,如果你弄清楚:-)。 – seeker 2012-02-22 17:28:30

1

将RAW DirectX/OpenGL OS上下文创建到此QLabel的winId()中并执行任何您想要的操作。我认为,这是高性能高清视频的最佳方式,也是唯一的方法:)有时您只需使用RAW的东西来实现最高性能并触摸电脑中的熨斗:)