2009-07-23 19 views
4

J'ai un CheckLabelTool dans un wx.ToolBar et je veux qu'un menu apparaisse directement sous le bouton de la souris. J'essaie d'obtenir l'emplacement de l'outil pour pouvoir définir la position du menu, mais tout ce que j'ai essayé (GetEventObject, GetPosition, etc.) me donne la position de la barre d'outils, donc le menu apparaît sous la barre d'outils , mais très loin de l'outil associé. Aucune suggestion? J'ai besoin de l'outil pour avoir la possibilité de basculer et de bitmap, mais je ne suis pas fixé sur CheckLabelTool s'il y a quelque chose d'autre qui fonctionnerait mieux.Wxpython: Positionnement d'un menu sous un bouton de la barre d'outils

Merci!

Répondre

6

lire la section sur la méthode PopupMenu sur wxpython.org:

« apparaît dans le menu donné dans les coordonnées spécifiées, par rapport à cette fenêtre , et retourne commande lorsque l'utilisateur a rejeté la menu. Si un élément de menu est sélectionné, l'événement de menu correspondant est généré et sera traitée comme d'habitude. Si la position par défaut est donnée, alors la position actuelle du curseur de la souris sera utilisé « .

Vous devez vous lier à l'événement EVT_MENU de votre outil de vérification. Une fois le bouton de l'outil coché, vous pouvez faire apparaître le menu. Si vous ne spécifiez pas l'emplacement du popup, il utilisera la position actuelle de la souris, ce qui est ce que vous voulez.

Si vous souhaitez que le menu pour faire apparaître à un endroit prédéterminé qui est indépendant de la souris, vous pouvez obtenir l'emplacement de l'écran de la barre d'outils et d'ajouter un décalage

Examinons le code:

[] Modifier: Pour montrer comment calculer la position de n'importe quel point sur un outil, j'ai modifié le code pour calculer et afficher divers points sur la barre d'outils une fois que vous avez cliqué sur un outil. Le menu apparaît dans le coin inférieur droit du bouton cliqué. Cela fonctionne pour moi sur Windows. Je suis curieux de savoir si elle ne se comporte pas sur d'autres plates-formes.]

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() 

parties de ce code proviennent de here.

+0

Merci pour votre réponse. Le problème n'était pas comment ouvrir le menu, c'était comment le positionner quand je ne peux pas obtenir la position d'un outil individuel dans la barre d'outils (la partie "ajouter un décalage" de votre réponse). J'ai trouvé une solution de contournement pour ce problème spécifique, mais pour l'avenir, j'aimerais toujours savoir comment obtenir la position (en pixels) d'un outil dans une barre d'outils, ou si c'est même possible. –

+0

Voir les modifications. Il va maintenant vous montrer le coin supérieur gauche et le coin inférieur droit de l'outil cliqué. Le menu apparaîtra dans le coin inférieur droit. – Mathieu

+0

Fonctionne bien dans Mint Linux en utilisant gnome. – Alan

Questions connexes