Python Tkinter按钮在使用热键后冻结程序



我正在尝试构建一个简单的自动点击程序,该程序具有启动/停止按钮和热键(使用Tkinter和Pynput(。每当我用启动按钮启动自动点击器时,它都能完美地工作,我可以停止它。然而,当我用热键启动自动点击机时,我无法用停止按钮停止它,因为它会冻结整个程序。

这是我的GUI的主要类:

class App(tk.Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__()
self.parent = parent
self.parent.bind("<Destroy>", self.exit)
self.clicker = Clicker(Button.left, 1)
self.clicker.start()
self.kb = Keyboard("<shift>+s", self.start_click)
self.kb.start()
btn_box = ttk.Combobox(self, values=BUTTONS, state="readonly")
btn_box.current(0)
btn_box.pack()
start = tk.Button(self, text="Start", command=self.start_click)
start.pack()
stop = tk.Button(self, text="Stop", command=self.stop_click)
stop.pack()
exit = tk.Button(self, text="Exit", command=self.exit)
exit.pack()

def start_click(self):
self.clicker.start_click()

def stop_click(self):
print("e")
self.clicker.stop_click()

def exit(self, event=None):
self.clicker.exit()
self.parent.quit()

这些是我的点击器和键盘类:

class Clicker(threading.Thread):
def __init__(self, button, delay):
super().__init__()
self.button = button
self.delay = delay
self.running = False
self.prog_running = True
self.mouse = Controller()

def start_click(self):
print("start")
self.running = True

def stop_click(self):
print("stop")
self.running = False

def exit(self):
self.running = False
self.prog_running = False

def run(self):
while self.prog_running:
while self.running:
self.mouse.click(self.button)
time.sleep(self.delay)
time.sleep(0.1)
class Keyboard(threading.Thread):
def __init__(self, keybind, command):
super().__init__()
self.daemon = True
self.hk = HotKey(HotKey.parse(keybind), command)

def for_canonical(self, f):
return lambda k: f(self.l.canonical(k))

def run(self):
with Listener(on_press=self.for_canonical(self.hk.press),
on_release=self.for_canonical(self.hk.release)) as self.l:
self.l.join()

有人知道为什么在使用热键后按下停止按钮时它会冻结吗?

当我使用self.quit()而不是self.destroy()时,我遇到了问题,但很可能,您的情况并非如此。

使用self.bind()添加快捷方式可能是一种解决方案,

例如:

#Importing the tkinter module
from tkinter import *
#Creating a window
root = Tk()
#Creating a label
txt = Label(root, text="Opened! But I'm closing, you know...").grid(row=1, column=1)
#Defining an action and binding it(root is the window's name)
def actionn(*args):
root.destroy()
root.bind('<Shift-S>', actionn)
#Showing the window and the label
root.mainloop()

你不能那样绑定shift,用self.parent.bind('<Shift-S>')绑定它我想它冻结是因为指定的快捷方式不起作用。。。

最新更新