Is this PyQt 4 python bug or wrongly behaving code?

我与影子孤独终老i 提交于 2019-11-30 02:57:41

问题


Following code should create the QGraphicsView widget which owns one QGraphicsScene having text inside of it:

#!/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_())

This opens the window, puts the text there, but after I close window - python dumps core and several issues are printed out:

(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)

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


回答1:


This is probably neither a PyQt bug, nor wrongly behaving code.

When python goes through its shutdown process, the order in which objects get deleted can be unpredictable. Occasionally, this may cause somewhat baffling error messages to appear.

Your script runs fine on my (non-Ubuntu) Linux machine - but when I close the window, I get this output:

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

Which, taken at face value, seems to make no sense at all...

However, it's usually pretty easy to get rid of such error messages by forcing the objects to be deleted in a different order.

One (slightly strange) way to do this is to just rename some of the objects. So for me, the error messages disappear if I simply change view to _view.

However, a perhaps better alternative is to make sure that certain key objects are connected together in a parent/child hierarchy:

    view = QGraphicsView()  
    scene = QGraphicsScene(view)

The reason for doing this, is that when deleteing an object, Qt will also automatically delete all of its descendant QObject nodes. This can help to ensure that the C++ side of PyQt objects is cleaned up before the python side (which is really at the core of what causes these kinds of problems).

Another possibility is to keep a global reference to the QApplication, and put everything else in a main function:

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:


It looks to be related to the QApplication object being deleted when quitting, but I'm not sure why. Your code worked fine for me under Windows but I got the same seg fault output as you under an Ubuntu install.

I managed to get a clean exit with the following code as a work around.

#!/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()


来源:https://stackoverflow.com/questions/12433491/is-this-pyqt-4-python-bug-or-wrongly-behaving-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!