Search code examples
pythontkinterkeyboard

Keyboard module doesn't work in a tkinter Gui


I wanted to create a keyboard whose keys were colored when I pressed the key on the keyboard. The code has no errors, but when the button is pressed, nothing happens: I don't now if is possible to do that keyboard with that module or i made some errors. Please, help me.

import tkinter as tk
import keyboard


class SensibleKeyboard:

    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Sensible Keyboard")
        self.root.resizable(False,False)
        self.root.geometry("520x265")

        #Titolo
        self.title = tk.Label(text = "SensibleKeyboard",font = ("Arial",26)).place(x = 120 ,y = 10)

        #Frame contenitore tastiera
        self.frame = tk.Frame(width = 520, height = 165, bg = "#fff")
        self.frame.place(x = 0, y = 100)

        #Tastiera grafica
        #Riga 1
        self.q =  tk.Button(self.frame,text = "Q", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 0 , y = 0)
        self.w =  tk.Button(self.frame,text = "W", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 52 , y = 0)
        self.e =  tk.Button(self.frame,text = "E", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 104 , y = 0)
        self.r =  tk.Button(self.frame,text = "R", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 156 , y = 0)
        self.t =  tk.Button(self.frame,text = "T", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 208 , y = 0)
        self.y =  tk.Button(self.frame,text = "Y", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 260 , y = 0)
        self.u =  tk.Button(self.frame,text = "U", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 312 , y = 0)
        self.i =  tk.Button(self.frame,text = "I", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 364 , y = 0)
        self.o =  tk.Button(self.frame,text = "O", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 416 , y = 0)
        self.p =  tk.Button(self.frame,text = "P", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 468 , y = 0)

        #Riga 2
        self.a =  tk.Button(self.frame,text = "A", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 17 , y = 56)
        self.s =  tk.Button(self.frame,text = "S", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 69 , y = 56)
        self.d =  tk.Button(self.frame,text = "D", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 121 , y = 56)
        self.f =  tk.Button(self.frame,text = "F", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 173 , y = 56)
        self.g =  tk.Button(self.frame,text = "G", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 225 , y = 56)
        self.h =  tk.Button(self.frame,text = "H", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 277 , y = 56)
        self.j =  tk.Button(self.frame,text = "J", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 329 , y = 56)
        self.k =  tk.Button(self.frame,text = "K", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 381 , y = 56)
        self.l =  tk.Button(self.frame,text = "L", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 433 , y = 56)

        #Riga 3
        self.z =  tk.Button(self.frame,text = "Z", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 40 , y = 112)
        self.x =  tk.Button(self.frame,text = "X", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 92 , y = 112)
        self.c =  tk.Button(self.frame,text = "C", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 144 , y = 112)
        self.v =  tk.Button(self.frame,text = "V", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 196 , y = 112)
        self.b =  tk.Button(self.frame,text = "B", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 248 , y = 112)
        self.n =  tk.Button(self.frame,text = "N", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 300 , y = 112)
        self.m =  tk.Button(self.frame,text = "M", height = 3, width = 6, activebackground = "black", activeforeground = "white").place(x = 352 , y = 112)

        #Funzione accensione da tastiera
        #Funzioni
        if keyboard.is_pressed("q"):
            self.q.config(bg = "blue")
        elif keyboard.is_pressed("w"):
            self.w.config(bg = "blue")
        elif keyboard.is_pressed("e"):
            self.e.config(bg = "blue")
        elif keyboard.is_pressed("r"):
            self.r.config(bg = "blue")
        elif keyboard.is_pressed("t"):
            self.t.config(bg = "blue")
        elif keyboard.is_pressed("y"):
            self.y.config(bg = "blue")
        elif keyboard.is_pressed("u"):
            self.u.config(bg = "blue")
        elif keyboard.is_pressed("i"):
            self.i.config(bg = "blue")
        elif keyboard.is_pressed("o"):
            self.o.config(bg = "blue")
        elif keyboard.is_pressed("p"):
            self.p.config(bg = "blue")
        elif keyboard.is_pressed("a"):
            self.a.config(bg = "blue")
        elif keyboard.is_pressed("s"):
            self.s.config(bg = "blue")
        elif keyboard.is_pressed("d"):
            self.d.config(bg = "blue")
        elif keyboard.is_pressed("f"):
            self.f.config(bg = "blue")
        elif keyboard.is_pressed("g"):
            self.g.config(bg = "blue")
        elif keyboard.is_pressed("h"):
            self.h.config(bg = "blue")
        elif keyboard.is_pressed("j"):
            self.j.config(bg = "blue")
        elif keyboard.is_pressed("k"):
            self.k.config(bg = "blue")
        elif keyboard.is_pressed("l"):
            self.l.config(bg = "blue")
        elif keyboard.is_pressed("z"):
            self.z.config(bg = "blue")
        elif keyboard.is_pressed("x"):
            self.x.config(bg = "blue")
        elif keyboard.is_pressed("c"):
            self.c.config(bg = "blue")
        elif keyboard.is_pressed("v"):
            self.v.config(bg = "blue")
        elif keyboard.is_pressed("b"):
            self.b.config(bg = "blue")
        elif keyboard.is_pressed("n"):
            self.n.config(bg = "blue")
        elif keyboard.is_pressed("m"):
            self.m.config(bg = "blue")
        else:
            pass     
    def start(self):
        self.root.mainloop()
sk = SensibleKeyboard()
sk.start()

Solution

  • You do not need the keyboard library to handle this.

    First lets fix your very redundant code. Instead of writing each button one at a time we can do this in a dynamic way based on a list of characters. At the same time we can store our buttons in a list that we can use to update the buttons on click.

    With the use of bind() we can check if one of the keys was press and then update the corresponding button in the list.

    By binding all Key Presses and all Key Releases we can use a method to check if one of those keys was from our list and if so update the button on key press and key release.

    import tkinter as tk
    
    
    class SensibleKeyboard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Sensible Keyboard")
            self.resizable(False, False)
            self.geometry("520x265")
            self.title = tk.Label(text="SensibleKeyboard",
                                  font=("Arial", 26)).grid(row=0, column=0, pady=20, sticky='ew')
            main_frame = tk.Frame(self)
            main_frame.grid(row=1, column=0, sticky='ew')
            self.orig_color = self.cget("background")
            self.btn_list = []
            btn_rows = ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM']
            row_pad = 0
            btn_ndex = 0
            for ndex, rows in enumerate(btn_rows):
                row_frame = tk.Frame(main_frame)
                row_frame.grid(row=ndex, column=0, sticky='ew', padx=(row_pad,0))
                row_pad += 20
                for row_ndex, value in enumerate([char for char in rows]):
                    self.btn_list.append(tk.Button(row_frame, text=value, height=3, width=6,
                                                   activebackground="black", activeforeground="white"))
                    self.btn_list[-1].grid(row=0, column=row_ndex)
                    btn_ndex += 1
            self.bind('<KeyPress>', lambda e: self.change_bg(e, 'p'))
            self.bind('<KeyRelease>', lambda e: self.change_bg(e, 'r'))
    
        def change_bg(self, event, press_type):
            print(event)
            c = event.char.upper()
            for btn_ndex, value in enumerate([char for char in 'QWERTYUIOPASDFGHJKLZXCVBNM']):
                if value == c:
                    if press_type == 'p':
                        self.btn_list[btn_ndex].config(bg='blue')
                    else:
                        self.btn_list[btn_ndex].config(bg=self.orig_color)
                    break
    
    
    if __name__ == '__main__':
        SensibleKeyboard().mainloop()