Привязать много ключей одновременно

#python #tkinter #binding

#python #tkinter #привязка

Вопрос:

Я заметил, что я быстро застрял, когда хотел создать игру, для которой требовались одновременные нажатия клавиш на Tkinter. Вот почему я решил создать виджет, который позволит пользователю получать все активные ключи.

Метод прост:

  • У меня есть набор
  • Когда нажата клавиша, я добавляю ее в набор
  • Когда ключ освобождается, я удаляю его из набора
  • Если пользователь хочет знать, какие клавиши нажаты, я просто возвращаю набор

Я выполнил этот код:

 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()
  

Теперь у меня ошибка, которую я не понимаю.

Когда я нажимаю A, Z, E, R, это работает; Но если я нажимаю A, Z, E, R T, это не работает (буква T не отображается). Однако, если я нажимаю только A, Z, E, T, это работает. Я полагал, что максимум равен 4, но я пробовал со многими другими ключами, и это не так. (Например, у меня такая же ошибка с W, X, C)

Почему возникает эта ошибка и что я могу сделать, чтобы ее решить?

Спасибо 🙂

PS: Я не знаю, почему я не могу поздороваться в начале своего сообщения.. Итак, я заканчиваю: Привет всем!

Ответ №1:

Возможный ответ здесь. В частности, на этой странице Википедии в разделе n-key rollover.

В принципе, ваша клавиатура не может принимать определенное количество клавиш, потому что они взаимодействуют по одной и той же схеме. Это аппаратное ограничение. Попробуйте сопоставить различные комбинации клавиш, чтобы увидеть, какие из них работают вместе, а какие нет.

Комментарии:

1. Спасибо за ваш ответ. Я думаю, вы правы. Я протестировал некоторые комбинации, которые не должны работать (согласно вашей странице в викпедии) и.. Это не работает. Итак, это было именно так. ^^ Спасибо за все. Проблема решена 🙂