Следующий код должен создать виджет 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
Ответ 1 · рейтинг 12 · ekhumoro
Вероятно, это не ошибка 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 узлов. Это может помочь гарантировать, что сторона C++ объектов PyQt будет очищена до стороны 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())
Ответ 2 · рейтинг 13 · Gary Hughes
Похоже, что это связано с удалением объекта 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()