WexyR WexyR - 1 month ago 10
Python Question

Bind many keys at the same time

I've noticed that i was quickly stuck when i wanted to do a game which needed simultaneous key presses on Tkinter. That's why i decided to create a widget which allow the user to get all active keys.

The methode is simple:


  • I've a set

  • When a key is pressed, I add it into the set

  • When a key is released, I discard from the set

  • If the user want to know which keys are pressed, I just return the set



I've done this code:

import tkinter as tk

class Tk_Multikey(tk.Frame):
"""Allow the user to get all actived keys"""

def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)

self.keysym = set()
self.keycode = set()
self.keysym_num = set()
master.bind('<KeyPress>', self.add_a_key, add='+')
master.bind('<KeyRelease>', self.discard_a_key, add='+')

def add_a_key(self, event):
"""When a key is pressed, add its keysym, keycode and keysym_num to the corresponding set"""

self.keysym.add(event.keysym.upper()) # the upper method prevents a
# bug when the user is using the Shift/Caplock key and a letter key
self.keycode.add(event.keycode)
self.keysym_num.add(event.keysym_num)


def discard_a_key(self, event):
"""When a key is released, discard its keysym, keycode and keysym_num to the corresponding set"""

self.keysym.discard(event.keysym.upper())
self.keycode.discard(event.keycode)
self.keysym_num.discard(event.keysym_num)


def __delattr__(self, nameattr):
"""The user is not allowed to delete a set"""
raise AttributeError("Unable to delete")

def get_keys(self):
return((self.keysym, self.keycode, self.keysym_num))


if __name__ == "__main__":

def update(event=None):
print("updating")
strvar_keysym.set(mtk.keysym)
strvar_keycode.set(mtk.keycode)
strvar_keysym_num.set(mtk.keysym_num)

root = tk.Tk()

mtk = Tk_Multikey(root)
mtk.pack()

root.bind('<KeyPress>', update, add='+')
root.bind('<KeyRelease>', update, add='+')

strvar_keysym = tk.StringVar()
strvar_keycode = tk.StringVar()
strvar_keysym_num = tk.StringVar()
update()

tk.Label(root, textvariable=strvar_keysym).pack()
tk.Label(root, textvariable=strvar_keycode).pack()
tk.Label(root, textvariable=strvar_keysym_num).pack()

root.mainloop()


Now I have a bug that i don't understand.

When I press A, Z, E, R, that works; But if I press A, Z, E, R T, that doesn't work (the T does not appear). However, if i only press A, Z, E, T, that works. I believed that the maximum was 4 but i've tried with many other key and it's not that. (I've the same bug with W, X, C for exemple)

Why this bug happens and what can i do to solve it?

Thank you :)

PS: I don't know why i can't say hello at the beginning of my message.. So i put it a the end: Hello there!

Answer

Possible answer here. Specifically this Wikipedia page under n-key rollover.

Basically, your keyboard cannot take a certain amount of keys because they communicate on the same circuit. It is a hardware limitation. Try mapping out different key combinations to see which ones work together and which don't.

Comments