Python Tkinter如何与听众一起工作?
我已经写了一个Tkinter,我希望有一个监听器来监视用户的键盘输入。但是,当我使用Python Tkinter如何与听众一起工作?,python,python-3.x,multithreading,tkinter,pynput,Python,Python 3.x,Multithreading,Tkinter,Pynput,我已经写了一个Tkinter,我希望有一个监听器来监视用户的键盘输入。但是,当我使用mainloop()启动Tkinter时,侦听器无法与它一起工作,并且将在我退出Tkinter之前启动 我曾尝试在Tkinter子单元中添加此侦听器,但效果不一样 def initialization(): print("Starting...") print("Start listener...") with mouse.Listener(on_click=onMouseClick) a
mainloop()
启动Tkinter时,侦听器无法与它一起工作,并且将在我退出Tkinter之前启动
我曾尝试在Tkinter子单元中添加此侦听器,但效果不一样
def initialization():
print("Starting...")
print("Start listener...")
with mouse.Listener(on_click=onMouseClick) as listener:
listener.join()
if __name__ == "__main__" :
root = tk.Tk()
root.geometry('800x80')
root.resizable(height=True, width=True)
root.overrideredirect(False)
root.title('vENC Console')
OneBtn = Button(root, command=initialization, text="One Button", width='30')
root.mainloop()
我怎样才能让他们一起工作?我需要使用多线程吗?与几乎所有GUI工具包一样,Tkinter是事件驱动的。这意味着Tkinter应该处理鼠标和键盘事件。 小部件可以通过添加特定事件的绑定来注册他们对事件感兴趣。Tkinter取决于事件的流程 本质上,
mainloop
等待事件发生(键盘、鼠标、超时),然后调用任何已注册的回调
添加另一个独立于Tkinter的事件处理程序将发生冲突。最重要的是,Tkinter不是线程安全的。如果必须使用线程,则应确保只有主线程使用Tkinter函数和方法
基本上,Tkinter和听者不能一起工作
因此,我建议您使用bind\u all
。
通过使用
bind\u all
方法(阅读相关内容),您可以在应用程序级别注册绑定,而不是为特定的小部件注册绑定。您可以这样编写绑定
listener = mouse.Listener(on_click=onMouseClick)
listener.start() # start thread
root.mainloop()
listener.stop() # stop thread
listener.join() # wait till thread really ends its job
不要在鼠标单击中使用returnfalse
,因为它结束了监听器
tkinter
有自己的方法来获取键和鼠标事件,所以也许你应该使用它们<当tkinter的窗口最小化且无法从系统获取事件时,如果您必须捕获事件,则代码>侦听器将非常有用
编辑:
import tkinter as tk
from pynput import mouse
def onMouseClick(*args):
print(args)
root = tk.Tk()
listener = mouse.Listener(on_click=onMouseClick)
listener.start() # start thread
root.mainloop()
listener.stop() # stop thread
listener.join() # wait till thread really ends its job
编辑:
import tkinter as tk
from pynput import mouse
def onMouseClick(*args):
print(args)
def initialization():
global listener
print("Starting...")
print("Start listener...")
listener = mouse.Listener(on_click=onMouseClick)
listener.start() # start thread
if __name__ == "__main__" :
listener = None
root = tk.Tk()
btn = tk.Button(root, command=initialization, text="One Button")
btn.pack()
root.mainloop()
# stop listener if it was created
if listener: # if listener is not None:
print("Stop listener...")
listener.stop() # stop thread
listener.join() # wait till thread really ends its job
编辑:带有停止侦听器按钮的示例
import tkinter as tk
from pynput import mouse
def onMouseClick(*args):
print(args)
def on_start():
global listener
if not listener:
print("Start listener...")
listener = mouse.Listener(on_click=onMouseClick)
listener.start() # start thread
else:
print("listener already running")
def on_stop():
global listener
if listener:
print("Stop listener...")
listener.stop() # stop thread
listener.join() # wait till thread really ends its job
listener = None # to inform that listener doesn't exist
else:
print("listener not running")
if __name__ == "__main__" :
print("Starting...")
listener = None # to keep listener
root = tk.Tk()
btn = tk.Button(root, command=on_start, text="Star Mouse Listener")
btn.pack()
btn = tk.Button(root, command=on_stop, text="Stop Mouse Listener")
btn.pack()
root.mainloop()
# stop listener if it was created
if listener: # if listener is not None:
print("Stop listener...")
listener.stop() # stop thread
listener.join() # wait till thread really ends its job
当用户关注或不关注tkinter时,你是否试图监视鼠标点击?@HenryYik事实上,我想监视键盘输入,例如,当用户发送键F5时,我将在tkinter中执行一些操作。他们的网站上有一个非阻塞解决方案
listener=mouse.listener(…)
然后listener.start()
。我尝试使用Thread.start和Join,但效果不同。鼠标侦听器是一个threading.Thread,因此如果调用listen.Join()
它将等待线程终止,从而阻塞tkinter的主线程。我不确定什么不起作用-你能澄清一下吗?它起作用了!但是为什么mainloop()
必须介于listener.start()
和listener.join()之间呢?我可以先使用mainloop
,然后启动Listener,然后使用Join()?mailoop()
一直工作,直到您关闭窗口-所以mainloop()
之后的Listener将在您关闭窗口后创建。所以,当我使用“Listener.start()”然后使用“mainloop()”启动Listener时,mainloop不会杀死Listener?仅块侦听器?然后join()将让它们一起工作?侦听器创建单独的线程来运行它-因此mainloop()
不会阻止它,也不会杀死它。它们同时工作,但线程不同。而join()
仅用于等待侦听器关闭(线程关闭)。您甚至可以跳过join()
,但随后可能会出现错误,即线程未正确关闭(或类似情况)。是的,我删除了join(),然后重试。当我杀死“mainloop()”时,侦听器将同时被杀死。谢谢!它帮助我更深入地理解线程!