2012-09-15 1 views
11

다음 코드 :이 창을 엽니 다이 PyQt 4 파이썬 버그 또는 잘못 작동하는 코드입니까? 그것의 내부 일 QGraphicsScene 가진 텍스트 소유를 QGraphicsView 위젯 작성해야

#!/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: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 파이썬 - QT4는 4.9.1-2ubuntu1

답변

10

이것은 PyQt 버그가 아니며 잘못 작동하는 코드도 아닙니다.

파이썬이 종료 프로세스를 수행 할 때 개체가 삭제되는 순서는 예측할 수 없습니다. 때로는 이로 인해 다소 복잡한 오류 메시지가 나타날 수 있습니다.

스크립트 내 (비 우분투) 리눅스 시스템에서 잘 실행

-하지만 난 창을 닫을 때, 나는이 출력 얻을 :

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

어떤 얼굴 값에서 촬영을에서 아무 의미가없는 것 같다 모두 ...

그러나 일반적으로 개체를 다른 순서로 삭제하여 이러한 오류 메시지를 제거하는 것은 매우 쉽습니다.

하나의 (약간 이상한) 방법은 일부 개체의 이름을 바꾸는 것입니다. 그래서 나를 위해 단순히 view_view으로 변경하면 오류 메시지가 사라집니다.

그러나, 아마도 더 나은 대안은 특정 키 객체가 상위/하위 계층 구조에서 함께 연결되어 있는지 확인하는 것입니다

view = QGraphicsView() 
    scene = QGraphicsScene(view) 

이 일을하는 이유는, 인 객체를 삭제 중 때, Qt는 것 그 또한 하위 노드 인 QObject 노드를 모두 자동으로 삭제합니다. 이것은 Python 객체의 C++ 측이 파이썬 측 (실제로 이런 종류의 문제를 일으키는 핵심 부분) 전에 정리되도록 보장 할 수 있습니다.

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

'view'를'scene'의 부모로 만드는 것이 최선의 방법입니다, IMO. ;-) – Peque

+0

LOL이 잘 끝나고, 일들을 별도의'main()'메쏘드로 옮기고'exec_()'를 리턴하면 "segfault" – sjm324

13

그것은 t을 본다 o 종료 할 때 삭제되는 QApplication 오브젝트와 관련되어 있어야하지만 이유는 확실하지 않습니다. 귀하의 코드는 Windows에서 잘 작동하지만 우분투 설치시 동일한 seg 오류 출력을 얻었습니다.

다음 코드를 사용하여 깨끗한 종료를 얻을 수있었습니다.

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

을'app.deleteLater()'한 트릭을 추가 :

또 다른 가능성은 QApplication에 글로벌 참조를 유지하고 main 함수에서 다른 모든 것들을 넣어하는 것입니다. 감사! – Onlyjus