2012-09-15 15 views
11

seguito il codice dovrebbe creare il widget QGraphicsView che possiede una QGraphicsScene avere il testo all'interno di esso:Si tratta di un bug Python Python 4 o di un codice errato?

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

Si apre la finestra, mette il testo lì, ma dopo la chiusura della finestra - pitone discariche core e diversi problemi vengono stampati 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) 

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

risposta

10

Questo probabilmente non è un bug PyQt, né un codice errato.

Quando Python passa attraverso il processo di arresto, l'ordine in cui gli oggetti vengono eliminati può essere imprevedibile. Occasionalmente, ciò potrebbe causare la visualizzazione di messaggi di errore un po 'sconcertanti.

Lo script funziona bene sulla mia macchina (non-Ubuntu) Linux - ma quando chiudo la finestra, ottengo questo output:

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

Il che, considerata al valore nominale, sembra avere alcun senso tutto ...

Tuttavia, di solito è abbastanza semplice eliminare questi messaggi di errore forzando la cancellazione degli oggetti in un ordine diverso.

Uno (un po 'strano) modo di farlo è di rinominare solo alcuni degli oggetti. Quindi, per me, i messaggi di errore scompaiono se cambio semplicemente view a _view.

Tuttavia, una forse meglio alternativa è quella di fare in modo che certi oggetti chiave sono collegati tra loro in una gerarchia padre/figlio:

view = QGraphicsView() 
    scene = QGraphicsScene(view) 

Il motivo per fare questo, è che quando deleteing un oggetto, Qt sarà inoltre elimina automaticamente tutti i suoi nodi discendenti QObject. Questo può aiutare a garantire che il lato C++ degli oggetti PyQt sia ripulito prima del lato python (che è veramente al centro di ciò che causa questo tipo di problemi).

Un'altra possibilità è quella di mantenere un riferimento globale per la QApplication, e mettere tutto il resto in una funzione 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

Rendere 'view' il genitore di' scene' è il modo migliore per farlo, IMO. ;-) – Peque

+0

LOL ben fatto, spostando le cose in un metodo 'main()' separato e restituendo 'exec _()' mi sono sbarazzato del mio "segfault" – sjm324

13

sembra t o essere collegato all'oggetto QApplication che viene eliminato quando si esce, ma non sono sicuro del perché. Il tuo codice ha funzionato bene per me sotto Windows ma ho ottenuto lo stesso errore di seg in uscita con un'installazione Ubuntu.

Sono riuscito a ottenere un'uscita pulita con il seguente codice come soluzione.

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

Aggiunta 'app.deleteLater()' ha fatto il trucco. Grazie! – Onlyjus

Problemi correlati