我正在使用 PyQt 开发一个 GUI,对一些实验中收集的数据进行可视化分析。GUI 要求用户指明要分析的数据所在的目录:
class ExperimentAnalyzer(QtGui.QMainWindow):
## other stuff here
def loadExperiment(self):
directory = QtGui.QFileDialog.getExistingDirectory(self,
"Select Directory")
## load data from directory here
GUI 提供了一种播放功能,通过该功能,用户可以看到实验数据如何随时间变化。这是通过QTimer实现的:
def playOrPause(self):
## play
if self.appStatus.timer is None:
self.appStatus.timer = QtCore.QTimer(self)
self.appStatus.timer.connect(self.appStatus.timer,
QtCore.SIGNAL("timeout()"),
self.nextFrame)
self.appStatus.timer.start(40)
## pause
else:
self.appStatus.timer.stop()
self.appStatus.timer = None
如果我播放数据的时间序列,然后暂停,然后尝试更改目录以加载新实验中的数据,我会遇到分段错误。
使用一些调试打印,我发现应用程序在我调用时崩溃
QtGui.QFileDialog.getExistingDirectory(self, "Select Directory")
在loadExperiment方法中。
我对 Qt 很陌生,我认为我没有正确处理计时器。
我在 Ubuntu 10.04 上使用 PyQt 4.9、Python 2.7.3。
编辑1:
在卢克的回答之后,我回到了我的代码。
这是nextFrame方法,每次定时器发出超时信号时都会调用。它更新包含在 GUI 中的 QGraphicsScene 元素:
def nextFrame(self):
image = Image.open("<some jpg>")
w, h = image.size
imageQt = ImageQt.ImageQt(image)
pixMap = QtGui.QPixmap.fromImage(imageQt)
self.scene.clear()
self.scene.addPixmap(pixMap)
self.view.fitInView(QtCore.QRectF(0, 0, w, h),
QtCore.Qt.KeepAspectRatio)
其中 self.scene 和 self.view 对象先前已在 GUI 构造函数中实例化为
self.view = QtGui.QGraphicsView(self)
self.scene = QtGui.QGraphicsScene()
self.view.setScene(self.scene)
我发现评论这一行:
# self.scene.addPixmap(pixMap)
并重复上面报告的相同操作序列,不再发生分段错误。
编辑2:
使用 gdb(使用 python-dbg)运行应用程序,结果是在调用 QPainter::drawPixmap 之后发生分段错误。
(gdb) bt
#0 0xb6861f1d in ?? () from /usr/lib/i386-linux-gnu/libQtGui.so.4
#1 0xb685d491 in ?? () from /usr/lib/i386-linux-gnu/libQtGui.so.4
#2 0xb693bcd3 in ?? () from /usr/lib/i386-linux-gnu/libQtGui.so.4
#3 0xb69390bc in ?? () from /usr/lib/i386-linux-gnu/libQtGui.so.4
#4 0xb6945c77 in ?? () from /usr/lib/i386-linux-gnu/libQtGui.so.4
#5 0xb68bd424 in QPainter::drawPixmap(QPointF const&, QPixmap const&) () from /usr/lib/i386-linux-gnu/libQtGui.so.4
因此,这不是与计时器处理有关的问题,正如我在第一个实例中所相信的那样。
发生分段错误是因为我对 pixMap 做错了什么。