17

IPython で非常に単純な PySide (および PyQt) チュートリアルを行っています。1 つのチュートリアルでは、いくつかのスライダーを含むウィンドウを作成して、スロットとシグナルを実演します。

実行中のデモ アプリケーションのウィンドウを閉じると、次のエラーが表示されます。

An exception has occurred, use %tb to see the full traceback.
SystemExit: 0
To exit: use 'exit', 'quit', or Ctrl-D.

だから私は %tb を実行し、これを取得します:

SystemExit                                Traceback (most recent call last)
/Workspaces/scratch/<ipython-input-1-88966dcfb499> in <module>()
     33 
     34 if __name__ == "__main__":
---> 35     main()

/Workspaces/scratch/<ipython-input-1-88966dcfb499> in main()
     29         w.show()
     30         app.exec_()
---> 31         sys.exit(0)
     32 
     33 

SystemExit: 0

コードをもう一度実行しようとすると、次のようになります。

RuntimeError: A QApplication instance already exists.

それが役立つ場合、ここに私のコード:

from PySide.QtCore import *
from PySide.QtGui import *
import sys

class MyWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self, None)

        vbox = QVBoxLayout(self)

        self.slider1 = QSlider(Qt.Horizontal)
        self.slider1.setRange(0, 99)
        self.slider1.setValue(0)
        vbox.addWidget(self.slider1)

        self.slider2 = QSlider(Qt.Horizontal)
        self.slider2.setRange(0, 99)
        self.slider2.setValue(99)
        vbox.addWidget(self.slider2)

        self.slider1.valueChanged.connect(self.slider2Changed)

    def slider2Changed(self, position):
        self.slider2.setValue(self.slider2.maximum() - position)

def main():
        app = QApplication(sys.argv)
        w = MyWindow()
        w.show()
        app.exec_()
        sys.exit(0)

if __name__ == "__main__":
    main()

Python を使用してコードを実行してもエラーは発生しません。

python myexample.py

このエラーは、IPython (ノートブック、qtconsole、または通常の ipython ターミナルを含む) でコードを実行した場合にのみ発生します。

更新: 私の主な問題は、アプリケーションをすばやく簡単に再実行できないことです。コードをもう一度実行しようとすると、次のようになります。

RuntimeError: A QApplication instance already exists.

それはIPythonの高速でインタラクティブな性質を殺します:(

4

5 に答える 5

27

この回答は、ipython-users メーリング リストの Matthias BUSSONNIER のおかげです。

実行中のデモ アプリケーションのウィンドウを閉じると、次のエラーが表示されます。例外が発生しました。%tb を使用して完全なトレースバックを表示してください。システム終了: 0

sys.exit(0) は使用しないでください。Python を終了するのではなく、IPython を実行しているからです。

(実際の) コマンド ラインからアプリを実行し、ステータスを返したい場合は、これを追加してください。

コードをもう一度実行しようとすると、次のようになります:
RuntimeError: QApplication インスタンスが既に存在します。

これは、バグとは見なされないため、「修正されない」PySide バグです。

https://github.com/ipython/ipython/issues/1124 )
およびhttp://bugs.pyside.org/show_bug.cgi?id=855を参照してください。

QApplication は 1 つのインスタンスしか持つことができず、アプリを終了することは、オブジェクトを削除するのに十分な理由とは見なされないようです...

上記の問題からこのコードを使用できます。

app=QtGui.QApplication.instance() # checks if QApplication already exists 
if not app: # create QApplication if it doesnt exist 
     app = QtGui.QApplication(sys.argv)

これは、私の現在のニーズに対して十分なソリューションでした。

于 2012-06-05T15:47:29.617 に答える
10

必要なことは、次のように QApplication を後で削除することです。

app = QApplication(sys.argv)
app.aboutToQuit.connect(app.deleteLater)

このコードを使用すると、IPython または他の場所で何度でもアプリケーションを再実行でき、qt アプリケーションを閉じるたびにオブジェクトが Python で削除されます。

于 2013-11-29T19:13:24.230 に答える
5

sys.exitSystemExitインタプリタを終了するために単にレイズします。

ipythonSysExitは対話モードでスクリプトを実行するときにキャッチするため、これは実際にはエラーではありませんが、ipython の機能により、スクリプトの実行時に対話型インタープリターがシャットダウンされるのを回避できます。

于 2012-06-04T21:45:56.280 に答える