wxPython:如何暂时禁用所有加速器?

时间:2009-09-16 14:56:16

标签: wxpython

如何暂时禁用wxPython应用中的所有加速器?

例如,我有一个特殊的TextCtrl,我想用它来记录单个按键,我不希望将按键视为加速器。虽然该小部件具有焦点,但我想禁用所有加速器。

在wxPython邮件列表中,建议我将EVT_UPDATE_UI绑定到所有菜单ID,并根据窗口小部件关注的内容启用或禁用事件。这意味着我必须知道我的所有菜单ID,但我不知道。这适用于允许用户定义自己的菜单项以及可能自己的加速器的应用程序。

2 个答案:

答案 0 :(得分:0)

如果要禁用加速键,SetAcceleratorTable可以正常工作 例如在这里我使用SetAcceleratorTable禁用加速键,禁用快捷键有点困难,我使用hacky方式更改所有菜单文本,但顶级菜单仍然打开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()

你说如果你知道所有的id,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)

答案 1 :(得分:-1)

要禁用加速器,您可以将加速器表设置为预定义的wx.NullAcceleratorTable

ctrl.SetAcceleratorTable(wx.NullAcceleratorTable)

我这样做是为了永久禁用帧中的加速器表,我假设如果你想暂时这样做,你可以根据需要交换表。