如何 运行 pynput.Listener 同时与 tkinter.Tk().mainloop()
How to run pynput.Listener simultaneously with tkinter.Tk().mainloop()
我是一名老师。我教数学,但由于教育面临人力资源危机,我有一些额外的职责。我教孩子们一些编程,他们做得很好。现在我想和他们一起做一个蛇游戏,但是我在我的 GUI 应用程序中实现多线程时遇到了问题。
我发现了类似的情况,但没有解决方案。像这儿:
Using the keyboard to move the character in a maze
和这里:
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()
我预计 window 到 运行 与听众同时进行。相反,我的代码会监听键盘,然后(在我击落监听器之后)弹出 window。当我在调用主循环后调用监听器时它会反转,然后首先出现 window 并且在我将其击落后监听器开始工作。
Listener
是一个线程,所以如果你加入它,你的主线程将等到它结束继续处理。
您可以只创建一个 Listener
对象而无需 with
语句,它将 运行 沿着主线程(直到回调函数将 return False
)
tkinter
中不需要 Listener
。您可以使用 root.bind
将功能分配给按下和释放事件。
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()
您也可以为每个按键单独分配功能
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()
Tcl/Tk 文档中的键符:https://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm
顺便说一句:
如果您想同时 运行 tkinter
和 pynput
那么您必须在 join()
之前完成
with Listener(on_press=on_press, on_release=on_release) as listener:
root = Tk()
root.mainloop()
#listener.stop()
listener.join()
或
listener = Listener(on_press=on_press, on_release=on_release)
listener.start()
root = Tk()
root.mainloop()
#listener.stop()
listener.join()
我是一名老师。我教数学,但由于教育面临人力资源危机,我有一些额外的职责。我教孩子们一些编程,他们做得很好。现在我想和他们一起做一个蛇游戏,但是我在我的 GUI 应用程序中实现多线程时遇到了问题。
我发现了类似的情况,但没有解决方案。像这儿: Using the keyboard to move the character in a maze 和这里: 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()
我预计 window 到 运行 与听众同时进行。相反,我的代码会监听键盘,然后(在我击落监听器之后)弹出 window。当我在调用主循环后调用监听器时它会反转,然后首先出现 window 并且在我将其击落后监听器开始工作。
Listener
是一个线程,所以如果你加入它,你的主线程将等到它结束继续处理。
您可以只创建一个 Listener
对象而无需 with
语句,它将 运行 沿着主线程(直到回调函数将 return False
)
tkinter
中不需要 Listener
。您可以使用 root.bind
将功能分配给按下和释放事件。
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()
您也可以为每个按键单独分配功能
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()
Tcl/Tk 文档中的键符:https://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm
顺便说一句:
如果您想同时 运行 tkinter
和 pynput
那么您必须在 join()
with Listener(on_press=on_press, on_release=on_release) as listener:
root = Tk()
root.mainloop()
#listener.stop()
listener.join()
或
listener = Listener(on_press=on_press, on_release=on_release)
listener.start()
root = Tk()
root.mainloop()
#listener.stop()
listener.join()