Reputation: 705
Hello i am wondering if there is a way to check if a certain key is being held down.
Here is an example of the situation
self.button2.Bind(wx.EVT_LEFT_DOWN, self.clickedbutton)
def clickedbutton(self, e):
if (Control is held down while the button has been clicked):
print "it works"
Thanks
Upvotes: 4
Views: 3483
Reputation: 1
WxPython has a function wx.GetKeyState(key) that returns True if the key is currently down. It succeeds for all keys on Windows. But the documentation states that "In wxGTK, this function can be only used with modifier keys ( WXK_ALT , WXK_CONTROL and WXK_SHIFT ) when not using X11 backend currently".
Here is a portable alternative. It uses a filter function as part of the App to filter all events. It captures the key up and key down events. It can be extended to other events.
class App(wx.App):
def __init__(self):
self.keys_down = []
def FilterEvent(self, event):
typ = event.GetEventType()
if typ == wx.EVT_KEY_DOWN.typeId:
key = event.GetKeyCode() # This is always upper case
if key not in self.keys_down:
self.keys_down.append(key)
print (self.keys_down)
elif typ == wx.EVT_KEY_UP.typeId:
key = event.GetKeyCode()
self.keys_down.remove(key)
print (self.keys_down)
return -1
def QuiskGetKeyState(self, key): # Replacement for wx.GetKeyState()
if 97 <= key <= 122: # convert to upper case
key -= 32
return key in self.keys_down
Upvotes: 0
Reputation: 6730
self.button2.Bind(wx.EVT_LEFT_DOWN, self.clickedbutton)
def clickedbutton(self, e):
if wx.GetKeyState(wx.WXK_CONTROL):
print "it works"
Upvotes: 9
Reputation: 7512
The problem with using only wx for this is that you need a KeyEvent to access the actual state of the control key. Since you need this information outside of such an event you need to keep track of it manually, and the problem with that is that it is easy to miss a KeyEvent since only focused controls get them and you can't count on them propagating.
The foolproof way would be to utilize some platform specific way of querying this information, if you are on windows look in to pyHook or win32api for this.
In some cases though the wx only approach can work and here is how you do it:
import wx
class Example(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
btn = wx.Button(self, label="press me")
self.Sizer = wx.BoxSizer()
self.Sizer.Add(btn)
self.ctrl_down = False
self.Bind(wx.EVT_KEY_UP, self.OnUpdateCtrlState)
self.Bind(wx.EVT_KEY_DOWN, self.OnUpdateCtrlState)
btn.Bind(wx.EVT_KEY_UP, self.OnUpdateCtrlState)
btn.Bind(wx.EVT_KEY_DOWN, self.OnUpdateCtrlState)
btn.Bind(wx.EVT_BUTTON, self.OnButton)
def OnUpdateCtrlState(self, event):
self.ctrl_down = event.ControlDown()
print self.ctrl_down
event.Skip()
def OnButton(self, event):
if self.ctrl_down:
wx.MessageBox("control down")
app = wx.App(False)
app.TopWindow = f = Example()
f.Show()
app.MainLoop()
Upvotes: 4