2016-10-12 8 views
2

私はPyQt4とmatplotlibを使ってguiを作っています。私はthis非常に有用な質問/私が使用しようとしているタブ付きGUIウィンドウを作成する上での答えを見つけた。すべてがうまくいくように見えます(マイナーな調整がいくつかあります)。しかし、私がメインウィンドウを閉じるたびに、私は "Pythonが予期せず終了する"エラーとセグメンテーション違反を取得します。これはプログラムの動作には影響しませんが、むしろ迷惑で、問題を見つけたいと思います。今exit matplotlibのPyQtセグメンテーションフォルト

、私は以下のMWEに降りで何が起こっていたかを把握しようとしているときに(または最小壊れた例であれば、あなたなります)問題は、ウィンドウにフィギュアのキャンバスを追加しているようだ

import sys 

import matplotlib 
matplotlib.use('Qt4agg') 

import matplotlib.pyplot as plt 

import numpy as np 

from PyQt4 import QtCore 
from PyQt4 import QtGui as qt 


if __name__ == "__main__": 

    fig = plt.figure() 

    x, y = np.random.randn(2, 40) 

    ax = fig.add_subplot(111) 

    ax.plot(x, y, 'o')  

    ax.hold(False) 

    app = qt.QApplication(sys.argv) 

    # ui = MplMultiTab(figures=[fig], labels=["yay"]) 

    ui = qt.QMainWindow() 
    ui.main_frame = qt.QWidget() 

    vbox = qt.QVBoxLayout() 

    vbox.addWidget(fig.canvas) 

    ui.main_frame.setLayout(vbox) 
    ui.setCentralWidget(ui.main_frame) 

    ui.show() 

    sys.exit(app.exec_()) 

あたかも私がこれをしない代わりに空のgui(remove vbox.addWidget(fig.canvas)を削除する)のようにすべてがうまくいき、segfaultはありません。

誰かが間違っているのを見たり、matplotlibやpyqtのバグですか?興味深いことに、に似たGUIを設定した場合、セグメンテーションフォルトはありませんが、実際にはどのような違いがあるのか​​分かりません。

私はこれをPython 3.5.2で実行しています。これは、OSX 10.11.6でPyTt verion 4.11.4とmatplotlib 1.5.3を使用しています。 PyQt documentationで述べたよう

答えて

3

:のQtを使用して、任意のGUIアプリケーションについて

は、正確に1つのはQApplicationオブジェクト、アプリケーションは、任意の時点で0、1、2以上のウィンドウを持っているかどうかに関係なく存在します。

数字を生成するときが黙って作成されている可能性が高いと思います。このQApplicationは、Figureを画面に表示するためにpyplotによって作成されたGUIである、FigureManagerのメインイベントループを管理するために使用されます。

QPlotですでにQApplicationが作成されているので、コード内でqt.QApplication(sys.argv)がさらに呼び出されたときにエラーが発生するのが普通だと思いますが、Qtはそれを見ずに別のQApplication 。これはおそらく、アプリケーションを終了しようとしたときに衝突を引き起こしているものです。そのpyplotはそれを見て、構築するのではなく、それを使用していますので、あなたはQApplication内部pyplotコードを置き、独自の1 -

1:私は、この問題を解決するために、3種類のオプションが表示さ

import sys 
import matplotlib 
matplotlib.use('Qt4agg') 
import matplotlib.pyplot as plt 
import numpy as np 
from PyQt4 import QtGui as qt 

if __name__ == '__main__': 

    app = qt.QApplication(sys.argv) 

    fig, ax = plt.subplots() 
    x, y = np.random.randn(2, 40) 
    ax.plot(x, y, 'o') 

    ui = qt.QWidget() 
    vbox = qt.QVBoxLayout() 
    vbox.addWidget(fig.canvas) 
    ui.setLayout(vbox) 
    ui.show() 

    sys.exit(app.exec_()) 

2 - 使用してください既に代わりに新しいものを作成するpyplotによって構築はQApplicationへのポインタ:

import sys 
import matplotlib 
matplotlib.use('Qt4agg') 
import matplotlib.pyplot as plt 
import numpy as np 
from PyQt4 import QtGui as qt 

if __name__ == '__main__': 

    fig, ax = plt.subplots() 
    x, y = np.random.randn(2, 40) 
    ax.plot(x, y, 'o') 

    app = qt.QApplication.instance() 

    ui = qt.QWidget() 
    vbox = qt.QVBoxLayout() 
    vbox.addWidget(fig.canvas) 
    ui.setLayout(vbox) 
    ui.show() 

    sys.exit(app.exec_()) 

3からmatplotlib documentationで示唆したように、MPLの数字を埋め込む際にQtインターフェイスにpyplotインタフェースを使用してオブジェクト指向APIを使用することを避けます代わりに。この場合、MWEは次のように書き換えられます。

import sys 
import matplotlib 
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg 
import numpy as np 
from PyQt4 import QtGui as qt 

if __name__ == '__main__': 

    app = qt.QApplication(sys.argv) 

    fig = matplotlib.figure.Figure() 
    canvas = FigureCanvasQTAgg(fig) 
    ax = fig.add_subplot(111) 
    x, y = np.random.randn(2, 40) 
    ax.plot(x, y, 'o') 

    ui = qt.QWidget() 
    vbox = qt.QVBoxLayout() 
    vbox.addWidget(canvas) 
    ui.setLayout(vbox) 
    ui.show() 

    sys.exit(app.exec_()) 
+0

ありがとうJean-Sebastien。私は実際に私のコードを再編成している間に番号1に偶然出会ったので、今私はなぜ私の問題がなくなったのか知っています。これは素晴らしいと書かれた答えbtwです。 – Andrew

関連する問題