Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Это ошибка Python PyQt 4 или неправильное поведение кода?

Автор вопроса: jhnsnОтветов: 2

Следующий код должен создать виджет 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

pyqtpyqt4segmentation-faultqgraphicsscene

Ответы

Ответ 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()

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы