11

次のコードは、テキストを含む1つの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がコアをダンプし、いくつかの問題が出力されます。

(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

4

2 に答える 2

13

終了時に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()
于 2012-09-17T10:17:00.353 に答える
12

これはおそらくPyQtのバグでも、コードの誤動作でもありません。

Pythonがシャットダウンプロセスを実行するとき、オブジェクトが削除される順序は予測できない可能性があります。場合によっては、これにより、やや不可解なエラーメッセージが表示されることがあります。

スクリプトは私の(Ubuntu以外の)Linuxマシンで正常に実行されますが、ウィンドウを閉じると、次の出力が表示されます。

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

これは、額面通りに考えると、まったく意味がないようです...

ただし、通常、オブジェクトを別の順序で強制的に削除することで、このようなエラーメッセージを取り除くのは非常に簡単です。

これを行う1つの(少し奇妙な)方法は、オブジェクトの一部の名前を変更することです。したがって、私にとっては、単にに変更viewするとエラーメッセージが消えます_view

ただし、おそらくより良い代替策は、特定のキーオブジェクトが親/子階層で相互に接続されていることを確認することです。

    view = QGraphicsView()  
    scene = QGraphicsScene(view)

これを行う理由は、オブジェクトを削除するときに、Qtがそのすべての子孫QObjectノードも自動的に削除するためです。これは、PyQtオブジェクトのC ++側がPython側の前にクリーンアップされることを保証するのに役立ちます(これは、これらの種類の問題を引き起こす原因の核心です)。

もう1つの可能性は、へのグローバル参照を保持し、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())
于 2012-09-17T16:14:14.097 に答える