Home > Software engineering >  Are keyboard library and tkinter compatible?
Are keyboard library and tkinter compatible?

Time:12-09

I am trying to control the values of variables using the arrow keys on my keyboard to move a square around live on a tkinter canvas. I have no error message but when i run it Python 3.11, the canvas pops up but nothing happens when i press the keys. I'm using

from tkinter import *
from keyboard import *
tk=Tk()
tk.attributes('-fullscreen',True)
canvas=Canvas(tk, width=1366, height=768, background='#fff')
canvas.pack()
colors=[[(255, 255, 255) for i in range(223)] for i in range(321)]

def colr(lis):
    a=lis[0]
    b=lis[1]
    c=lis[2]
    if a%6<10:
        va='0' str(a%6)
    else:
        va=hex(a%6).replace('0x','')
    if b%6<10:
        vb='0' str(b%6)
    else:
        vb=hex(b%6).replace('0x','')
    if c%6<10:
        vc='0' str(c%6)
    else:
        vc=hex(c%6).replace('0x','')
    return '#%s'%(va vb vc)

def fill_rect(a,b,c,d,e):
    a=a 683
    b=-b 384
    if type(e)==str:
        canvas.create_rectangle(a 2,b 2,c a 2,d b 2,fill=e,outline='')
    else:
        canvas.create_rectangle(a 2,b 2,c a 2,d b 2,fill=colr(e),outline='')
  #Modify the value if the color at pixel x,y
    for x in range(c):
        for y in range(d):
            if (a x)>=0 and (a x)<=320 and (b y)>=0 and (b y)<=222:
                colors[a x][b y]=e

xinc=0
yinc=0

fill_rect(xinc,yinc,10,10,[0,0,0])

while True:
    if is_pressed("left arrow")==True:
        xinc=xinc-1
        fill_rect(xinc,yinc,10,10,[0,0,0])
    if is_pressed("right arrow")==True:
        xinc=xinc 1
        fill_rect(xinc,yinc,10,10,[0,0,0])
    if is_pressed("up arrow")==True:
        yinc=yinc 1
        fill_rect(xinc,yinc,10,10,[0,0,0])
    if is_pressed("down arrow")==True:
        yinc=yinc-1
        fill_rect(xinc,yinc,10,10,[0,0,0])

I don't really know how how the "is_pressed()" works so maybe it's just not the good function or even the right library so if you recommand another one i'll gladly take advice.

CodePudding user response:

You may have an easier time using tkinter's built-in event bindings

so instead of checking things like

if is_pressed("left arrow")==True:
    xinc = xinc-1
    fill_rect(xinc, yinc, 10, 10, [0,0,0])

you would write something like

def handle_event(event):
    global xinc
    global yinc
    if event.keysym == 'Left':
        xinc=xinc-1
        fill_rect(xinc,yinc,10,10,[0,0,0])
    elif event.keysym == 'Right':
        xinc=xinc 1
        fill_rect(xinc,yinc,10,10,[0,0,0])
    elif event.keysym == 'Up':
        yinc=yinc 1
        fill_rect(xinc,yinc,10,10,[0,0,0])
    elif event.keysym == 'Down':
        yinc=yinc-1
        fill_rect(xinc,yinc,10,10,[0,0,0])


# bind the keyboard events to your root window
# you could also bind them to the canvas: 'canvas.bind(...)'
tk.bind('<Left>', handle_event)
tk.bind('<Right>', handle_event)
tk.bind('<Up>', handle_event)
tk.bind('<Down>', handle_event)

CodePudding user response:

You should not be using the keyboard module when writing tkinter. Tkinter handles all keyboard events for you.

The way you handle keyboard events in tkinter is to create functions that should be called when keys are pressed. You can then bind that function to a keyboard event.

For example, in your code you could create a function that looks like this:

def left_arrow(event):
    global xinc
    xinc=xinc-1
    fill_rect(xinc,yinc,10,10,[0,0,0])

You can then bind that function to the <Left> event on the canvas to call the function:

canvas.bind("<Left>", left_arrow)

You must also be sure to give the canvas the keyboard focus, since it doesn't get the focus by default.

canvas.focus_set()

This isn't the only solution. You can also bind all keys to the same function, and examine the passed-in event object to see what key was pressed. You could also bind to the root window or to all windows (if you have more than one).

There's much more to learn about event processing in tkinter, and it's covered in most tkinter tutorials, such as the one at tkdocs.com.

  • Related