wxPython: Wie alle Beschleuniger vorübergehend deaktivieren?
-
07-07-2019 - |
Frage
Wie kann ich vorübergehend deaktivieren alle Beschleuniger in einer WxPython app?
Zum Beispiel habe ich eine besondere TextCtrl, die ich verwenden möchte, einen einzigen Tastendruck aufzeichnen, und ich möchte nicht, dass keypress wie ein Beschleuniger behandelt werden. Während das Widget den Fokus hat möchte ich alle Beschleuniger deaktivieren.
Auf der wxPython-Mailingliste wurde vorgeschlagen, ich EVT_UPDATE_UI allen Menü-IDs binden und aktivieren oder deaktivieren Sie das Ereignis basierend auf welche Widget konzentriert. Das bedeutet, ich habe alle ids mein Menü wissen, aber ich weiß nicht. Dies ist für eine Anwendung, die Benutzer definieren ihre eigenen Menüpunkte und möglicherweise ihre eigenen Beschleuniger können.
Lösung
Wenn Sie Zugriffstasten deaktiviert werden soll, tut SetAcceleratorTable Arbeit z.B. hier verwende ich SetAcceleratorTable Zugriffstasten zu deaktivieren, Shortcut-Tasten deaktivieren ist etwas schwierig, ich ändern alle Menütexte eine hacky Weise verwende, aber Top-Menü öffnet sich nach wie vor auf Alt-m aber der Rest sind deaktiviert.
Aletrnatively ich glaube, Sie EVT_CHAT / EVT_KEY_UP für Rahmen und dessen Kind zu fangen und leicht Ereignisse blockieren, aber es müssen Sie vorsichtig sein.
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()
Sie sagte EVT_UPADTE_UI
arbeiten können, wenn Sie alle IDs wissen, denn das kann man nur Schleife durch alle Menüpunkte
for i in range(self.menuBar.GetMenuCount()):
menu = self.menuBar.GetMenu(i)
enableMenu(menu, i)
for menuItem in menu.GetMenuItems():
enableMenu(menuItem)
Andere Tipps
Um die Beschleuniger deaktivieren Sie die Beschleunigertabelle auf die predifined wx.NullAcceleratorTable einstellen
ctrl.SetAcceleratorTable(wx.NullAcceleratorTable)
Ich habe dies getan, um dauerhaft den Beschleuniger Tabelle in Frames zu deaktivieren, und ich nehme an, wenn Sie dies vorübergehend tun mögen, können Sie nur die Tabellen tauschen je nach Bedarf.