2012-09-15 17 views
11

siguiente código debe crear el widget QGraphicsView que posee una QGraphicsScene tener texto dentro de ella:¿Este Python 4 es un error o código de comportamiento erróneo?

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

Esto abre la ventana, pone el texto allí, pero después de cerrar la ventana - pitón volcado de núcleo y se imprimen varias cuestiones salida:

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

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

Respuesta

10

Probablemente no sea un error de PyQt ni un código de comportamiento incorrecto.

Cuando python pasa por el proceso de apagado, el orden en que se eliminan los objetos puede ser impredecible. Ocasionalmente, esto puede causar que aparezcan mensajes de error algo desconcertantes.

Su escritura funciona bien en mi máquina (no Ubuntu) Linux - pero cuando cierro la ventana, me da este resultado:

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

que, tomadas en su valor nominal, parece no tener ningún sentido todos ...

Sin embargo, generalmente es bastante fácil deshacerse de dichos mensajes de error forzando a los objetos a eliminarse en un orden diferente.

Una forma (algo extraña) de hacer esto es cambiar el nombre de algunos de los objetos. Entonces, para mí, los mensajes de error desaparecen si simplemente cambio view a _view.

Sin embargo, una alternativa quizás mejor es asegurarse de que ciertos objetos clave están conectados entre sí en una jerarquía de padre/hijo:

view = QGraphicsView() 
    scene = QGraphicsScene(view) 

La razón para hacer esto, es que cuando deleteing un objeto, Qt también elimina automáticamente todos sus nodos descendentes QObject. Esto puede ayudar a asegurar que el lado C++ de los objetos PyQt se limpia antes que el lado Python (que es realmente el núcleo de lo que causa este tipo de problemas).

Otra posibilidad es mantener una referencia global a la QApplication, y poner todo lo demás en función 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()) 
+0

Hacer 'view' el padre de' scene' es la mejor manera de hacerlo, IMO. ;-) – Peque

+0

LOL bien hecho, moviendo cosas a un método 'main()' separado y devolviendo 'exec _()' se deshizo de mi "segfault" – sjm324

13

parece t o estar relacionado con la eliminación del objeto QApplication al salir, pero no estoy seguro de por qué. Su código funcionó bien para mí en Windows, pero obtuve el mismo resultado seg seg de usted en una instalación de Ubuntu.

Logré obtener una salida limpia con el siguiente código como solución alternativa.

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

Adición 'app.deleteLater()' hizo el truco. ¡Gracias! – Onlyjus

Cuestiones relacionadas