2013-01-31 2 views
2

마우스를 클릭하면 wxPython 창의 내부에있는 matplotlib 숫자 위에 상황에 맞는 메뉴를 표시하고 싶습니다.Matplotlib 및 wxPython PopupMenu 협력

불행히도 클릭을 감지하면 PopupMenu 메서드가 호출되지만 팝업을 반환하거나 표시하지 않습니다. (이것은 Windows 7 호스트가있는 VirtualBox 내부의 우분투 12.10의 주식 Python과 같습니다.)

여기까지입니다. 나는 무엇을 놓치고 있습니까? 즉 PopupMenu을 실제로 표시하려면 어떻게해야합니까?

import wx 
import numpy 
import matplotlib 
matplotlib.use('WXAgg') 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas 
from wxPython.wx import * 

class MatplotlibContext(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, -1, 'some title') 
     self.panel = wx.Panel(self) 
     self.fig = Figure() 
     self.canvas = FigCanvas(self.panel, -1, self.fig) 
     self.axes = self.fig.add_subplot(111) 
     x = numpy.linspace(0, 6.28) 
     y = numpy.sin(x) 
     self.axes.plot(x, y) 
     self.canvas.draw() 
     self.canvas.mpl_connect('button_press_event', self.context_menu)   
     self.vbox = wx.BoxSizer(wx.VERTICAL) 
     self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) 
     self.panel.SetSizer(self.vbox) 
     self.vbox.Fit(self) 

    def context_menu(self, event): 
     print 'in context_menu callback: clicked at (%g, %g)' % (event.x, event.y) 
     menu = wxMenu() 
     item_id = wxNewId() 
     menu.Append(item_id, 'item') 
     wx.EVT_MENU(menu, item_id, self.callback) 
     self.PopupMenu(menu, wx.Point(event.x, event.y)) 
     menu.Destroy() 

    def callback(self, event): 
     print 'menu selection: %r' % event.GetId() 

app = wx.PySimpleApp() 
app.frame = MatplotlibContext() 
app.frame.Show() 
app.MainLoop() 

편집 2013-01-31 : 코드의 수정 오타. 수정 된 질문 :

위의 코드는 VirtualBox에서 12.10을 실행하거나 12.04를 직접 설치 한 두 대의 다른 컴퓨터에서 작동하지 않지만 대부분 12.10에서 실행되는 네 번째 컴퓨터에서 작동합니다. 왜 차이가 있는지 전혀 알 수 없습니다.

그렇지 않으면, 내 질문은 지금 추측 :

  • 을 내가 위/아래로 문제를 조정 해결 방법은? (창 위쪽에서 특정 거리를 클릭하면 그 거리가 아래에서부터 표시됩니다.)
  • PopupMenu를 열고 (선택적으로 닫으면) 기본 창을 닫으면 프로세스가 종료되지 않습니다 . 이 문제를 어떻게 해결할 수 있습니까?

편집 2013년 10월 2일 : 버전 정보이, 내가 파이썬 2.7.4,하기 matplotlib 1.2.1와 우분투 13.04를 실행하는거야 작동하지 않는 시스템 중 하나에 대한

, 및 wx 2.8.12.1.

+0

당신의 코드는 Fedora 18에서 주식 python 2.7.3으로 작동합니다; 유일한 문제는 메뉴가 잘못된 위치에 나타나고 클릭이 발생한 곳이 아니라는 것입니다. –

+0

대부분 Windows 7에서도 작동합니다. 그것은 약간의 오류와 경고를 주지만 메뉴가 나타납니다. Y 축 좌표는 차트 내에서 되돌아가는 것처럼 보입니다. – Fenikso

+0

좌표를 수정해야합니다. 시스템의 창 밖에있을 가능성이 높습니다. 또한 여기에서'menu.Destory()'를 수정하십시오. – Fenikso

답변

1

wxpython/matplotlib (확실하지 않은 것들)의 조합을 사용하면 matplotlib 이벤트 처리기에서 모달 윈도우 객체를 표시하여 이벤트 루프를 잠글 수 있습니다. 문제는 matplotlib FigureCanvas가 마우스를 자동으로 해제하지 않기 때문에 파손이 발생했을 때입니다. 모달 대화 상자가 전에 마우스 입력 이벤트가 발생하기 전에 입력을 가져 오려고 시도합니다.

적어도 내가 만났던 경우에는 간단한 해결책이있는 것 같습니다. 삽입 : 이벤트 처리기 시작 부분에

event.guiEvent.GetEventObject().ReleaseMouse() 

+0

행운이 없습니다. 이 기능이 작동하지 않는 하나 이상의 컴퓨터 (질문에 추가 된 버전)에서 matplotlib 이벤트 핸들러는 후속 클릭이 context_menu에 대한 호출을 트리거한다는 점에서 계속 작동하지만 PopupMenu에 대한 호출은 결코 팝업을 표시하지 않으며 반환하지 않습니다. – ramcdougal