2013-07-27 2 views
0

사용자 입력에 따라 데이터를 표시하고 대화식으로 처리하기 위해 WX-MPL 앱을 개발 중입니다. WX 앱 내에서 작동하도록 MPL 마우스 이벤트를 설정하는 데 어려움을 겪고 있습니다.Wx Matplotlib 이벤트 처리

목표는 이전 처리에서 식별 된 피처의 시작 및 종료 시간을 묘사하는 일련의 편집 가능한 수직선을 만드는 것입니다. 사용자는 X 축을 따라 선을 드래그하고 불필요한 선을 삭제하고 새 선을 삽입 할 수 있어야합니다.

지금까지 표준 MPL 플롯 그림을 사용하여이 기능을 구현할 수있었습니다 (Tk라고 생각합니다). 이러한 클래스를 내 앱에 통합하려고하면 이벤트 처리로 인해 뭔가 잘못되어 가고 선 개체와 상호 작용하거나 새 선 개체를 만들 수 없습니다. 그래서 저는 한 걸음 물러나서 문제가 어디로 오는지 판단하기 위해 작업 예제에 복잡성을 추가하려고 노력했습니다.

단순한 WX 앱으로 작업 예제를 실행하면 NewVLineListener 클래스가 더 이상 button_press_events를 수신하지 않는 것처럼 보입니다. 아래는 내가 경험하고있는 특정 문제와 관련된 코드입니다.

내가 마우스 이벤트로 작업 한 것은 이번이 처음이며, 분명히 뭔가 빠졌습니다 ... 조언을 주시면 감사하겠습니다.

또한 WX 2.8.12 및 MPL 1.1.1rc를 실행 중입니다.

from matplotlib.figure import Figure 
import wx 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg 

class NewVLineListener: 
    global castLog, count, dvls, ax1 
    lock = None # only one can be animated at a time 
    def __init__(self, fig): 
     self.fig = fig 

    def connect(self): 
     'connect to all the events we need' 
     self.cidpressright = self.fig.canvas.mpl_connect(
     'button_press_event', self.on_press_right) 

    def on_press_right(self, event): 
     global count, castLog, dvls, ax1 
     print event.button 
     if event.button != 3: return 
     tag = 'Begin' 
     # Increase castLog Key to accomodate new Vline 
     count += 1 
     print 'count: ', count 
     # Set castLog values to x-value of triggering event 
     castLog[str(count)] = { tag:event.xdata } 
     # Spawn a new DraggableVline instance 
     color_map = {'Begin':'g', 'End':'r'} 
     dvl = DraggableVline(self.fig, ax1.axvline(x=castLog[str(count)][tag], linewidth=2, color=color_map[tag]), count, tag) 
     dvl.connect() 
     dvls.append(dvl) 

     canvas = self.fig.canvas 
     canvas.draw() 

class MainFrame(wx.Frame): 
     def __init__(self): 
      wx.Frame.__init__(self, None, wx.ID_ANY) 
      global castLog, count, ax1, dvls 
      fig = Figure() 
      canvas = FigureCanvasWxAgg(self, -1, fig) 
      ax1 = fig.add_subplot(111) 

      # Create empty dict that will hold new V-line Data 
      castLog = { } 
      dvls = [ ] 
      count = 0 

      # Instantiate New Vline Listener 
      NVL = NewVLineListener(fig) 
      NVL.connect() 

if __name__ == '__main__': 
     app = wx.PySimpleApp() 
     app.frame = MainFrame() 
     app.frame.Show() 
     app.MainLoop() 
+0

자신의 GUI에 임베드하려면'pyplot'을 임포트하지 마십시오. – tacaswell

+0

이것을 관리하기 쉬운 크기로 줄일 수 있습니까? 문제와 관련된 코드 만 포함하십시오. 이 많은 코드를 사용하면 누군가가 문제를 해결할 수있는 기회를 얻지 못할 가능성이 적습니다. – tacaswell

+0

tcaswell에게 감사드립니다. 필자는 제안한대로 코드를 작성한 다음 그림을 pyplot에서 matplotlib.figure 인스턴스로 변경했습니다. 여전히 동일한 핵심 이슈를 갖는 리스너는 button_press_event를받지 못합니다. –

답변

1

알았어!

NewVlineListener 객체에 대한 참조가 가비지 수집되어 이벤트가 수신되지 않았다고 생각합니다. 드래그 가능한 vline 객체에 대한 참조 배열에 NVL 객체 참조를 추가하면 예상대로 객체가 고정되어 이벤트를 수신합니다.

class MainFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY) 
     global castLog, count, ax1, dvls 
     fig = Figure() 
     canvas = FigureCanvasWxAgg(self, -1, fig) 
     ax1 = fig.add_subplot(111) 

     # Create empty dict that will hold new V-line Data 
     castLog = { } 
     dvls = [ ] 
     count = 0 

     # Instantiate New Vline Listener 
     NVL = NewVLineListener(fig) 
     NVL.connect() 
     dvls.append(NVL) # This keeps NVL reference from being garbage collected? 

난 여전히 NewVlineListener 개체의 이름을 지정하는 것은 주변의 참조를 유지하는 것만으로는 충분하지 않습니다 있다는 것이 흥미, 그리고 pyplot와 잘 작동하지만 지금은 WX와 함께, 그러나이 작동하는 것 같다.