TkInter keypress, keyrelease events
Solution 1:
Ok some more research found this helpful post which shows this is occuring because of X's autorepeat behaviour. You can disable this by using
os.system('xset r off')
and then reset it using "on" at the end of your script. The problem is this is global behaviour - not just my script - which isn't great so I'm hoping someone can come up with a better way.
Solution 2:
Autorepeat behavior is system dependent. In Win7,
down a
down a
down a
...
down a
up a
This is for less than a second.
Solution 3:
Well, this is a bit late now, but I have a solution that works. It's not great, but it does not require os.system overwriting system settings, which is nice.
Basically, I make a class that records the timing of key presses. I say that a key is down when it has been pressed in the last short amount of time (here, .1ms). To get a press, it is easy enough: if the key is not registered as pressed, trigger the event. For releases, the logic is harder: if there is a suspected release event, set a timer for a short time (here, .1s) and then check to make sure the key is not down.
Once you have validated a press or release, call the on_key_press or on_key_release methods in your code. As for those, just implement them the way you originally wanted them
I know this is not perfect, but I hope it helps!!
Here is the code:
Where you are initializing keypress events:
key_tracker = KeyTracker()
window.bind_all('<KeyPress>', key_tracker.report_key_press)
window.bind_all('<KeyRelease>', key_tracker.report_key_release)
key_tracker.track('space')
Here is my custom KeyTracker class:
class KeyTracker():
key = ''
last_press_time = 0
last_release_time = 0
def track(self, key):
self.key = key
def is_pressed(self):
return time.time() - self.last_press_time < .1
def report_key_press(self, event):
if event.keysym == self.key:
if not self.is_pressed():
on_key_press(event)
self.last_press_time = time.time()
def report_key_release(self, event):
if event.keysym == self.key:
timer = threading.Timer(.1, self.report_key_release_callback, args=[event])
timer.start()
def report_key_release_callback(self, event):
if not self.is_pressed():
on_key_release(event)
self.last_release_time = time.time()