I am a teacher. I teach math, but since education is facing human resources crisis, I have some additional duties. I teach kids a bit of programming, they do quite well. Now I’d like to make with them a snake game, but I have a problem achieving multithreading in my GUI app.
I found similar cases but no solutions. Like here: Using the keyboard to move the character in a maze and here: Tkinter.Tk() and threading
def on_press(key): print('{0} pressed'.format(key)) def on_release(key): if key == Key.esc: return False with Listener(on_press=on_press, on_release=on_release) as listener: listener.join() root = Tk() root.mainloop()
I expected the window to run simultaneously with the listener. instead, my code listens to the keyboard and then (after I shoot the listener down) pops the window up. it reverses when I call the listener after calling the mainloop, then first the window appears and after I shoot it down the listener is starting to work.
Advertisement
Answer
You don’t need Listener
in tkinter
. You can use root.bind
to assign function to events press and release.
from tkinter import * def on_press(event): #print('on_press: event:', event) #print('on_press: keysym:', event.keysym) print('{0} pressed'.format(event.keysym)) def on_release(event): #print('on_release: event:', event) #print('on_release: keysym:', event.keysym) print('{0} release'.format(event.keysym)) if event.keysym == 'Escape': print("exist program") root.destroy() root = Tk() root.bind('<KeyPress>', on_press) root.bind('<KeyRelease>', on_release) root.mainloop()
You can also assign function to every key separatelly
from tkinter import * def on_escape(event): print("exist program") root.destroy() root = Tk() root.bind('<Escape>', on_escape) #root.bind('<KeyPress-Escape>', on_press_escape) #root.bind('<KeyRelease-Escape>', on_release_escape) root.mainloop()
Keysyms in Tcl/Tk documentation: https://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm
BTW:
If you want to run tkinter
and pynput
at the same time then you have to do it before join()
with Listener(on_press=on_press, on_release=on_release) as listener: root = Tk() root.mainloop() #listener.stop() listener.join()
or
listener = Listener(on_press=on_press, on_release=on_release) listener.start() root = Tk() root.mainloop() #listener.stop() listener.join()