2009-09-16 2 views
-1

Как временно отключить все ускорители в приложении wxPython?wxPython: как временно отключить все ускорители?

Например, у меня есть специальный TextCtrl, который я хочу использовать для записи одного нажатия клавиши, и я не хочу, чтобы это нажатие клавиши обрабатывалось как ускоритель. Хотя этот виджет имеет фокус, я хочу отключить все ускорители.

В списке рассылки wxPython было предложено привязать EVT_UPDATE_UI ко всем идентификаторам меню и включить или отключить событие на основе того, что виджет сосредоточил. Это означает, что я должен знать все мои идентификаторы меню, но я этого не делаю. Это приложение, которое позволяет пользователям определять свои собственные пункты меню и, возможно, собственные ускорители.

+0

какую ОС вы ориентируетесь? или это кросс-платформенный? –

+0

кросс-платформа, хотя подавляющее большинство наших пользователей находятся на linux –

ответ

-1

Чтобы отключить акселераторы вы можете установить таблицу акселератора в predifined wx.NullAcceleratorTable

ctrl.SetAcceleratorTable(wx.NullAcceleratorTable) 

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

+0

Это не работает. Я попытался установить таблицу нулевого ускорителя для элемента управления, для панели, в которой находится элемент управления, рамки, в которой находится панель, и строки меню, которая является частью фрейма. Во всех случаях ускорители, привязанные к строке меню, будут стрелять. –

+0

Я вижу, мой плохой ... Я пропустил проблему меню, указанную в вашем вопросе, и NullAcceleratorTable не меняет ярлыки меню. – tom10

0

Если вы хотите отключить клавиши ускорителя, SetAcceleratorTable работает , например. здесь я использую SetAcceleratorTable, чтобы отключить клавиши ускорителя, отключить клавиши быстрого доступа немного сложно, я использую хакерский способ изменения всех текстов меню, но главное меню все еще открывается на alt-m, но отдых отключен.

Я думаю, вы можете поймать EVT_CHAT/EVT_KEY_UP для фрейма и его дочернего элемента и легко блокировать события, но там вам нужно быть осторожным.

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

Вы сказали EVT_UPADTE_UI может работать, если вы знаете, все идентификаторы, для этого вы можете просто цикл через все пункты меню

for i in range(self.menuBar.GetMenuCount()): 
    menu = self.menuBar.GetMenu(i) 
    enableMenu(menu, i) 
    for menuItem in menu.GetMenuItems(): 
     enableMenu(menuItem) 
Смежные вопросы