2009-07-23 3 views
4

У меня есть CheckLabelTool в wx.ToolBar, и я хочу, чтобы меню всплывало прямо под ним при щелчке мыши. Я пытаюсь найти местоположение инструмента, поэтому я могу установить положение меню, но все, что я пробовал (GetEventObject, GetPosition и т. Д.), Дает мне позицию панели инструментов, поэтому, следовательно, меню появляется под панелью инструментов , но очень далеко от соответствующего инструмента. Какие-либо предложения? Мне нужен инструмент, чтобы иметь возможность переключения и растрового изображения, но я не исправлен в CheckLabelTool, если есть что-то еще, что будет работать лучше.Wxpython: позиционирование меню под кнопкой панели инструментов

Спасибо!

ответ

6

Прочитайте раздел о PopupMenu метода на wxpython.org:

«Всплывает данное меню в указанных координатах, относительно это окно, и возвращает управление, когда пользователь отклонил меню. Если выбран пункт меню, соответствующее событие меню генерируется и будут обработаны как обычно. Если позиция по умолчанию задается тогда текущее положение курсора мыши будет использоваться «.

Вам необходимо привязать к событию EVT_MENU вашего инструмента проверки. После того, как кнопка инструмента отмечена, вы можете открыть меню вверх. Если вы не укажете местоположение всплывающего окна, оно будет использовать текущую позицию мыши, что вам и нужно.

Если вы хотите, чтобы меню всплывал в заранее определенном месте, которое не зависит от мыши, вы можете получить расположение экрана на панели инструментов и добавить смещение

Давайте посмотрим на код:

[Редактирование: Чтобы показать, как вычислить положение любой точки на инструменте, я изменил код для вычисления и отображения различных точек на панели инструментов после нажатия на инструмент. Меню появляется в правом нижнем углу нажатой кнопки. Он работает для меня в Windows. Я хотел бы знать, если он не ведет себя и на других платформах.]

import wx 

class ViewApp(wx.App): 
    def OnInit(self): 
     self.frame = ToolFrame(None, -1, "Test App")  
     self.frame.Show(True) 
     return True   

class MyPopupMenu(wx.Menu): 
    def __init__(self, parent): 
     wx.Menu.__init__(self) 

     self.parent = parent 

     minimize = wx.MenuItem(self, wx.NewId(), 'Minimize') 
     self.AppendItem(minimize) 
     self.Bind(wx.EVT_MENU, self.OnMinimize, id=minimize.GetId()) 

    def OnMinimize(self, event): 
     self.parent.Iconize() 

class ToolFrame(wx.Frame): 
    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self, parent, id, title, size=(350, 250)) 

     self.toolbar = self.CreateToolBar() 
     self.tool_id = wx.NewId() 
     for i in range(3): 
      tool_id = wx.NewId() 
      self.toolbar.AddCheckLabelTool(tool_id, 'Tool', wx.EmptyBitmap(10,10)) 
      self.toolbar.Bind(wx.EVT_MENU, self.OnTool, id=tool_id) 
     self.toolbar.Realize() 
     self.Centre() 
     self.Show() 

    def OnTool(self, event): 
     if event.IsChecked(): 
      # Get the position of the toolbar relative to 
      # the frame. This will be the upper left corner of the first tool 
      bar_pos = self.toolbar.GetScreenPosition()-self.GetScreenPosition() 

      # This is the position of the tool along the tool bar (1st, 2nd, 3rd, etc...) 
      tool_index = self.toolbar.GetToolPos(event.GetId()) 

      # Get the size of the tool 
      tool_size = self.toolbar.GetToolSize() 

      # This is the upper left corner of the clicked tool 
      upper_left_pos = (bar_pos[0]+tool_size[0]*tool_index, bar_pos[1]) 

      # Menu position will be in the lower right corner 
      lower_right_pos = (bar_pos[0]+tool_size[0]*(tool_index+1), bar_pos[1]+tool_size[1]) 

      # Show upper left corner of first tool in black 
      dc = wx.WindowDC(self) 
      dc.SetPen(wx.Pen("BLACK", 4)) 
      dc.DrawCircle(bar_pos[0], bar_pos[1], 4)   

      # Show upper left corner of this tool in blue 
      dc.SetPen(wx.Pen("BLUE", 4)) 
      dc.DrawCircle(upper_left_pos[0], upper_left_pos[1], 4)   

      # Show lower right corner of this tool in green 
      dc.SetPen(wx.Pen("GREEN", 4)) 
      dc.DrawCircle(lower_right_pos[0], lower_right_pos[1], 4)   

      # Correct for the position of the tool bar 
      menu_pos = (lower_right_pos[0]-bar_pos[0],lower_right_pos[1]-bar_pos[1]) 

      # Pop up the menu 
      self.PopupMenu(MyPopupMenu(self), menu_pos) 

if __name__ == "__main__": 
    app = ViewApp(0) 
    app.MainLoop() 

Части этого кода происходят из here.

+0

Спасибо за ваш ответ. Проблема заключалась не в том, как открыть меню, а в том, как позиционировать его, когда я не могу получить позицию отдельного инструмента на панели инструментов (часть «добавление смещения» вашего ответа). Я нашел обходной путь для этой конкретной проблемы, но в будущем мне все равно хотелось бы узнать, как получить позицию (в пикселях) инструмента на панели инструментов, или если это даже возможно. – 2009-07-27 16:11:59

+0

См. Правки. Теперь он покажет вам верхний левый угол и нижний правый угол щелкнутого инструмента. Меню появится в правом нижнем углу. – Mathieu

+0

Работает отлично в Mint Linux с помощью gnome. – Alan

Смежные вопросы