线程:在GUI线程之外使用pixmap是不安全的

2024-05-16 02:59:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个音乐播放器,它使用挤压播放(一个挤压盒控制器应用程序)检查状态。长话短说,我正在使用线程检查每5秒挤压播放的状态。如果歌曲标题发生更改,我会让它更新标签(Qlabel、唱片图稿(QPixmap)等。但是,当我要求它通过线程更新时,我会发现在GUI线程之外使用pixmap是不安全的。

如何在设置QPixmap的同时进行线程处理?

示例代码:

#self.sq.getArtwork() returns variable with the image
coverArt = self.sq.getArtwork()
coverPixMap = QtGui.QPixmap()
coverPixMap.loadFromData(coverArt)
self.albumArt.setPixmap(coverPixMap)

非常感谢!

更新: 我试着用Emit做了下面的操作,但是不起作用,有人能看看我做错了什么吗?

def setNewArtwork(self, image):
    coverPixMap = QtGui.QPixmap()
    coverPixMap.convertFromImage(image)
    icon = QtGui.QIcon(coverPixMap)
    item.setIcon(icon)

def getNewArtwork(self):
    coverArt = self.sq.getArtwork()
    icon = QtGui.QImage(coverArt)
    self.emit(QtCore.SIGNAL('setNewArtwork(QImage)'), icon)

Tags: imageself状态defsq线程icon我会
3条回答

要回答有关如何在python中发出信号的问题:

不同于C++,当发出用户定义的EEM> PYQT信号(相对于Qt 1)时,应该省略签名。

因此,要发出信号,请执行以下操作:

thread.emit(QtCore.SIGNAL('newArtworkAvailable'), icon)

要连接到信号,请执行以下操作:

widget.connect(thread, QtCore.SIGNAL('newArtworkAvailable'),
               widget.setNewArtwork)

我只想说清楚:

为了实现这一点,非gui线程必须发出信号,然后由主gui线程中的适当小部件接收信号。在非gui线程中创建QImage应该是可以的,但是不要试图在主线程之外调用任何与gui相关的方法。

注意:

我在这里使用了旧式的信号语法,因为这就是您所使用的。不过,您可能想看看PyQt的new-style signal and slot support,因为它更灵活,更像Python。

所有的图形Qt操作都应该在主线程中进行。其他线程实际上不允许调用Qt图形操作(可能包括pixmap)。

他们可以emit Qt signals到主线程。或者简单地(在Linux上)写入一个管道,让主thread等待该管道上的输入。

当然,您必须定义所需的信号(以及插槽)。在C++代码中,需要用^ {< CD1> }(或^ {CD2}}标记它们,而C++代码应该由moc处理。我不知道Python对应的是什么(也许Python反射能力已经足够了,我真的不知道)。然后,您必须将信号连接到插槽,并使用排队连接。我不知道用Python怎么做。

您可能需要将所有绘图作业发送到主线程。

相关问题 更多 >