11

以下代码应创建 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

4

2 回答 2

13

它看起来与退出时被删除的 QApplication 对象有关,但我不确定为什么。您的代码在 Windows 下对我来说运行良好,但在 Ubuntu 安装下我得到了与您相同的段错误输出。

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

#!/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()
于 2012-09-17T10:17:00.353 回答
12

这可能既不是 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())
于 2012-09-17T16:14:14.097 回答