以下代码应该创建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)
版本:蟒蛇2.72.7.3-0ubuntu3.1python-qt4 4.9.1-2ubuntu1
它看起来与退出时删除的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()
这可能既不是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
节点。这有助于确保PyQt对象的C++端在python端之前被清理干净(这实际上是导致这些问题的核心)。
另一种可能性是保留对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())