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

wxPython:如何暂时禁用所有加速器?,wxpython,Wxpython,如何临时禁用wxPython应用程序中的所有加速器 例如,我有一个特殊的TextCtrl,我想用它来记录一次按键,我不想让那个按键被当作加速器。当这个小部件有焦点时,我想禁用所有加速器 在wxPython邮件列表中,有人建议我将EVT_UPDATE_UI绑定到所有菜单ID,并根据小部件关注的内容启用或禁用事件。这意味着我必须知道我所有的菜单ID,但我不知道。这适用于允许用户定义自己的菜单项和可能自己的加速器的应用程序。要禁用加速器,可以将加速器表设置为预定义的wx.NullAccelerator

如何临时禁用wxPython应用程序中的所有加速器

例如,我有一个特殊的TextCtrl,我想用它来记录一次按键,我不想让那个按键被当作加速器。当这个小部件有焦点时,我想禁用所有加速器


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

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

ctrl.SetAcceleratorTable(wx.NullAcceleratorTable)

我这样做是为了在帧中永久禁用加速器表,我假设如果要临时执行此操作,可以根据需要交换表。

如果要禁用加速器键,SetAcceleratorTable可以工作 e、 这里我使用SetAcceleratorTable来禁用快捷键,禁用快捷键有点困难,我使用的是一种骇人的方式来更改所有菜单文本,但是顶部菜单仍然在alt-m上打开,但其余的都被禁用

从本质上说,我认为您可以捕捉帧及其子帧的EVT_CHAT/EVT_KEY_,并轻松阻止事件,但在这方面您需要小心

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\u UPADTE\u UI
可以工作,因为你可以循环浏览所有的菜单项

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

那不行。我尝试为控件、控件所在的面板、面板所在的框架以及作为框架一部分的菜单栏设置空加速表。在任何情况下,绑在菜单栏上的加速器都会开火。我明白了,我的坏。。。我错过了您问题中提到的菜单问题,NullAcceleratorTable不会更改菜单快捷方式。您的目标是哪个操作系统?还是跨平台?跨平台,尽管我们的绝大多数用户都在linux上