这是PyQt 4 python错误还是错误的代码?

时间:2012-09-15 00:14:37

标签: python-2.7 segmentation-fault pyqt pyqt4 qgraphicsscene

以下代码应创建QGraphicsView小部件,该小部件拥有一个QGraphicsScene,其中包含文本:

#!/usr/bin/python

import sys
from PyQt4.QtGui import *


if __name__ == '__main__':
  app = QApplication(sys.argv)

  view = QGraphicsView()  
  scene = QGraphicsScene()

  scene.addText("Hello!")

  view.setScene(scene)
  view.show();

  sys.exit(app.exec_())

这会打开窗口,将文本放在那里,但在关闭窗口后 - python转储核心并打印出几个问题:

(python:5387): Gtk-CRITICAL **: IA__gtk_container_add: assertion `GTK_IS_CONTAINER (container)' failed

(python:5387): Gtk-CRITICAL **: IA__gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
...clip...
... above message is shown many, many times ...
...clip...
(python:5387): Gtk-CRITICAL **: IA__gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
Segmentation fault (core dumped)

版本: python2.7 2.7.3-0ubuntu3.1 python-qt4 4.9.1-2ubuntu1

2 个答案:

答案 0 :(得分:13)

它看起来与退出时被删除的QApplication对象有关,但我不确定原因。你的代码在Windows下运行正常,但我在Ubuntu安装下得到了与你相同的seg错误输出。

我设法通过以下代码获得一个干净的退出作为解决方法。

#!/usr/bin/python

import sys
from PyQt4.QtGui import QApplication, QGraphicsView, QGraphicsScene


if __name__ == '__main__':
  app = QApplication(sys.argv)

  view = QGraphicsView()  
  scene = QGraphicsScene()

  scene.addText("Hello!")

  view.setScene(scene)
  view.show()

  app.exec_()
  app.deleteLater()
  sys.exit()

答案 1 :(得分:11)

这可能既不是PyQt错误,也不是错误的代码。

当python经历其关闭过程时,对象被删除的顺序可能是不可预测的。有时,这可能会导致出现令人困惑的错误消息。

你的脚本在我的(非Ubuntu)Linux机器上运行正常 - 但是当我关闭窗口时,我得到了这个输出:

$ python2 test.py 
QPixmap: Must construct a QApplication before a QPaintDevice
Aborted

从表面上看,这似乎毫无意义......

但是,通过强制以不同的顺序删除对象,通常很容易摆脱这些错误消息。

这样做的一种(有点奇怪的)方法是重命名一些对象。因此,对我来说,如果我只是将view更改为_view,则错误消息会消失。

但是,一个更好的选择是确保某些关键对象在父/子层次结构中连接在一起:

    view = QGraphicsView()  
    scene = QGraphicsScene(view)

执行此操作的原因是,在删除对象时,Qt还将自动删除其所有后代QObject节点。这有助于确保在python端之前清理PyQt对象的C ++端(这实际上是导致这些问题的核心)。

另一种可能性是保留对QApplication的全局引用,并将其他所有内容放在main函数中:

import sys
from PyQt4.QtGui import *

def main():
    view = QGraphicsView()
    scene = QGraphicsScene()
    scene.addText("Hello!")
    view.setScene(scene)
    view.show()
    return qApp.exec_()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    sys.exit(main())