2016-10-12 2 views
2

PyQt4와 matplotlib를 사용하여 GUI를 만들고 있습니다. 내가 사용하려고하는 탭이있는 GUI 윈도우를 만들 때 this 매우 유용한 질문/답변을 찾았습니다. 모든 것이 잘 작동하는 것처럼 보입니다 (몇 가지 사소한 조정이 필요함). 그러나 메인 윈도우를 닫을 때마다 세그먼트 결함과 함께 "파이썬 종료 예기치 않게"오류가 발생합니다. 이것은 프로그램 운영에 영향을주지는 않지만 다소 성가신 일이며 문제를 찾아 내고 싶습니다. 이제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 (제거 vbox.addWidget(fig.canvas))를 만드는 것처럼 모든 것이 잘되고 segfault가 없습니다.

누구나 틀린 것을 보거나 matplotlib 또는 pyqt의 버그입니까? 또한 흥미롭게도, 내가 guier를 this answer과 비슷하게 설정했다면 세분화 오류가 없지만 실제로 차이점이 무엇인지 알 수는 없습니다.

모두를위한 정보 나는 Python 3.5.2에서 Python 버전 4.11.4와 matplotlib 버전 1.5.3을 OSX 10.11.6에서 사용하고 있습니다. PyQt documentation에 명시된 바와 같이

답변

3

: Qt는을 사용하는 모든 GUI 응용 프로그램에 대한

는 정확하게 하나의 QApplication 객체, 응용 프로그램이 주어진 시간에 0, 1, 2 개 이상의 창문이 있는지 여부에 상관없이 존재한다.

그림을 생성 할 때 QApplication이 (가) pyplot에 의해 자동 생성됩니다. 이 QApplication은 그림을 화면에 보여주기 위해 pyplot에 의해 생성 된 GUI 인 FigureManager의 메인 이벤트 루프를 관리하는 데 사용됩니다.

그래서 QApplication이 이미 pyplot으로 생성 되었기 때문에 qt.QApplication(sys.argv)이 코드에서 더 아래로 호출 될 때 오류가 발생한다고 생각합니다. 그러나 다소 Qt가이를 보지 못했고 다른 QApplication . 아마도 응용 프로그램을 닫으려고 할 때 충돌을 일으키는 원인 일 것입니다. 그 pyplot 그것을보고 건설 대신 그것을 사용, 그래서 당신의 QApplication 내부의 pyplot 코드를 넣어 자신의 일 -

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 - 사용하십시오 의 QApplication에 포인터는 이미 대신 새로운 하나를 만드는 pyplot으로 구성 :

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