2017-11-22 3 views
1

QtWidget의 일부인 matplotlib 그림을 지우는 슬롯 메소드를 구현하려고합니다. 파이썬 3.6 및 3.5 Windows 7 및 10 시도한 및 동일한 동작을 얻을.Matplotlib이있는 PyQT5 슬롯은 아무런 효과가 없습니다.

제 문제는 코드의 기본 블록이나 그림 그리기 클래스 내에서 와이프 메서드를 호출 할 때 완벽하게 지울 수 있다는 것입니다. 그러나이 똑같은 방법이 PyQT 신호에 대한 슬롯으로 호출 될 때마다 slot은 실제로 활성화되지만 fig.clf()에 대한 호출은 그림을 지우지 않습니다. 주석이 실제로 그림을 삭제하거나 전체 응용 프로그램을 닫는 경우 것을 제표에

import sys 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import QApplication,QMainWindow, QSizePolicy,QWidget,QVBoxLayout, QPushButton 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 


class GraphPopulate(FigureCanvas): 

    def __init__(self, parent=None): 
     self.fig = Figure(figsize=(6,4)) 
     self.ax = self.fig.add_axes([0.07, 0.16, 0.95, 0.95]) # fraction of figure size # 
     FigureCanvas.__init__(self, self.fig) 
     self.setParent(parent) 
     x = [2000, 2001, 2002, 2003, 2004] 
     y = [10, 20, 30, 40, 50] 
     self.plt = self.ax.plot(x, y) 

     # self.wipe() # OK This one works as well 
     # self.plt.close(self.fig) # close the app, does not only clear figure 

    def wipe(self): 
     print('wipe start') 
     # del self.fig # close the app on second call, does not only clear figure !! 
     # self.plt.close(fig) # close the app, does not only clear figure 
     rc = self.fig.clf() 
     print('return code from clf() '+ str(rc)) 
     print('wipe stop') 


if __name__ == '__main__': 

    # create main window 
    app = QApplication(sys.argv) 
    MainWindow = QMainWindow() 
    MainWindow.resize(800, 600) 

    # create widget to be used by MathPlotlib 
    WidgetMatplot = QWidget(MainWindow) 
    WidgetMatplot.setGeometry(QRect(10, 40, 500, 500)) 

    # create Push Button with clicked signal linked to GraphPopulate.wipe() slot 
    button = QPushButton(MainWindow) 
    button.setText("Push Me !") 

    # add widget to vertical box layout 
    hbox = QVBoxLayout(MainWindow) 
    hbox.addWidget(WidgetMatplot) 
    hbox.addWidget(button) 

    g = GraphPopulate(WidgetMatplot) 

    button.pyqtConfigure(clicked=g.wipe) # NOT OK !!!!!!! g.wipe is triggered as prints statements show 
              # on console but self.fig.clf() has no effect 

    MainWindow.show() 
    # g.wipe() # OK 
    sys.exit(app.exec_()) 

내가 넣었습니다 의견 :

아래의 코드는 문제를 보여줍니다.

다른 호출보다 signa-slot 연결에서 "matplotlib context"가 호출 된 것처럼 보입니다.

나는 사소한 것을 놓칠 수 있습니다. 그렇게 유감스럽게 생각하지만 혼자 조사 할 방향을 찾지 못했습니다 ... 그래서 나는 당신들에게 그것을 알아내는 것에 의지합니다.

감사합니다 - Thibault

답변

0

코드에서 그림이 성공적으로 삭제되었습니다. 아무도 그림을 다시 그려야한다고 말하지 않았기 때문에 단지 그것을 보지 못했습니다.

그림을 다시 그려 보면 실제로 비어있는 것입니다.

def wipe(self): 
    self.fig.clf() 
    self.fig.canvas.draw_idle() 
+0

감사합니다. MainWindow.show() 다음에 메인 블록에있는 g.wipe()가 그리기 명령을 필요로하지 않는 이유는 무엇입니까? 이것은 슬롯 방법이 아닌 메인 프로그램 루프에 포함되어 있기 때문에? – Thib

+0

그림은'app.exec _()'에 처음 그려집니다. 즉,'와이프 '를 호출 한 후 *입니다. 그래서이 시점에서 그 인물은 이미 삭제되었습니다. 버튼을 누르면 그림이 이미 그려져 있으므로 변경 사항을 보려면 다시 그려야합니다. – ImportanceOfBeingErnest

+0

ok 나는 show() 함수 실행 시간에 드로잉이 수행되었다고 잘못 가정했다. 그러므로 내 질문 – Thib

관련 문제