2009-09-16 10 views
-1

Comment puis-je désactiver temporairement tous les accélérateurs dans une application wxPython? Par exemple, j'ai un TextCtrl spécial que je veux utiliser pour enregistrer une seule pression de touche, et je ne veux pas que cette touche soit traitée comme un accélérateur. Alors que ce widget a le focus je veux désactiver tous les accélérateurs.wxPython: comment désactiver tous les accélérateurs temporairement?

Sur la liste de diffusion wxPython, il a été suggéré de lier EVT_UPDATE_UI à tous les identifiants de menu et d'activer ou de désactiver l'événement en fonction de ce que le widget a mis au point. Cela implique que je dois connaître tous mes identifiants de menu, mais pas moi. C'est pour une application qui permet aux utilisateurs de définir leurs propres éléments de menu et potentiellement leurs propres accélérateurs.

+0

qui OS que vous ciblez? ou est-ce multi-plateforme? –

+0

cross plate-forme, même si la grande majorité de nos utilisateurs sont sur Linux –

Répondre

-1

Pour désactiver les accélérateurs, vous pouvez mettre la table d'accélérateur au wx.NullAcceleratorTable predifined

ctrl.SetAcceleratorTable(wx.NullAcceleratorTable) 

Je l'ai fait pour désactiver définitivement la table d'accélérateur dans des cadres, et je suppose que si vous voulez faire temporairement, vous pourriez juste échanger les tables au besoin.

+0

Cela ne fonctionne pas. J'ai essayé de définir une table d'accélérateur nulle pour le contrôle, pour le panneau dans lequel se trouve le contrôle, le cadre dans lequel se trouve le panneau et la barre de menus qui fait partie du cadre. Dans tous les cas, les accélérateurs attachés à la barre de menu tireront. –

+0

Je vois, mon mauvais ... J'ai raté le problème de menu indiqué dans votre question, et le NullAcceleratorTable ne change pas les raccourcis du menu. – tom10

0

Si vous voulez désactiver les touches de l'accélérateur, SetAcceleratorTable fonctionne par ex. ici j'utilise SetAcceleratorTable pour désactiver les touches de l'accélérateur, pour désactiver les touches de raccourci est un peu difficile, j'utilise une manière hacky de changer tous les textes de menu, mais le menu principal ouvre encore sur alt-m mais repos sont désactivés. Aletrnatively je pense que vous pouvez attraper EVT_CHAT/EVT_KEY_UP pour l'image et son enfant et bloquer facilement les événements, mais là, vous devrez faire attention.

import wx 

class MainFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, style=wx.DEFAULT_FRAME_STYLE|wx.WS_EX_PROCESS_UI_UPDATES, 
        parent=None,size=(400,300)) 
     self._setMenu() 
     self.Show() 
     self._menuTextMap = {} 
     self.btn = wx.Button(self, -1, "Disable Accel") 
     self.btn.Bind(wx.EVT_BUTTON, self._toggleAccel) 

    def _enableMenuShortcuts(self, enable): 
     if enable and not self._menuTextMap: 
      return 

     def enableMenu(menuItem, i=-1): 
      if i==-1:#item 
       text = menuItem.GetText() 
      else:#menu 
       text = self.menuBar.GetLabelTop(i) 

      if enable: 
       print text, 
       newText = self._menuTextMap[text] 
       print newText 
      else: 
       newText = text.replace('&','')+" disabled" 
       self._menuTextMap[newText] = text 

      if i: 
       menuItem.SetText(newText) 
      else: 
       self.menuBar.SetLabelTop(i,newText) 

     for i in range(self.menuBar.GetMenuCount()): 
      menu = self.menuBar.GetMenu(i) 
      enableMenu(menu, i) 
      for menuItem in menu.GetMenuItems(): 
       enableMenu(menuItem) 

    def _toggleAccel(self, event): 
     self.accelOn = not self.accelOn 
     if self.accelOn: 
      self.SetAcceleratorTable(self.aTable) 
      self._enableMenuShortcuts(True) 
      self.btn.SetLabel("Disable Accel") 
     else: 
      self.SetAcceleratorTable(wx.NullAcceleratorTable) 
      self._enableMenuShortcuts(False) 
      self.btn.SetLabel("Enable Accel") 
     #self.menuBar.SetAcceleratorTable(wx.NullAcceleratorTable) 

    def _setMenu(self): 
     self.menuBar = wx.MenuBar() 

     myMenu= wx.Menu() 
     accelList = [] 

     for i in range(9): 
      ID = wx.NewId() 
      myMenu.Append(ID, "Item &%s"%(i+1)) 
      wx.EVT_MENU(self, ID, self._onMenu) 
      accelList.append((wx.ACCEL_CTRL, ord('A')+i, ID)) 

     self.menuBar.Append(myMenu, "&My Menu") 
     self.SetMenuBar(self.menuBar) 
     self.accelOn=True 
     self.aTable = wx.AcceleratorTable(accelList) 
     self.SetAcceleratorTable(self.aTable); 

    def _onMenu(self, event): 
     item = self.menuBar.GetMenu(0).FindItemById(event.GetId()) 
     wx.MessageBox("Menu -> %s"%(item.GetItemLabel(),)) 

app = wx.PySimpleApp() 
app.SetTopWindow(MainFrame()) 
app.MainLoop() 

Vous avez dit EVT_UPADTE_UI peut fonctionner si vous connaissez tous les ids, pour que vous pouvez juste boucle à travers tous les éléments de menu

for i in range(self.menuBar.GetMenuCount()): 
    menu = self.menuBar.GetMenu(i) 
    enableMenu(menu, i) 
    for menuItem in menu.GetMenuItems(): 
     enableMenu(menuItem) 
Questions connexes