当前位置: 首页 > 知识库问答 >
问题:

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

高宏峻
2023-03-14

我试图建立一个简单的自动点击程序,它有开始/停止按钮和热键(使用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()

这些是我的Clicker和键盘课程:

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()

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

共有1个答案

罗昱
2023-03-14

当我使用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绑定它。父母亲绑定('

希望它解决了您的问题:)

 类似资料:
  • 我正在使用tkinter编写一个应用程序,当按下按钮时,该应用程序将连接到sql DB并运行sql查询。我遇到了这样一个问题:当sql querys方法运行时,GUI会说“没有响应”,当它完成时,它会恢复正常。我决定将sql查询放在它自己的线程中,将tkinter的主循环放在它自己的线程中,但它根本不工作。。。? 这是我的GUI,我将主循环放在线程0中 还有这里 我将sql查询运行方法放在线程1中

  • 当我运行任何JavaFX代码(甚至是hello world http://docs.oracle.com/JavaFX/2/get_started/hello_world.htm)并按下capslock键时,应用程序将冻结,直到关闭caps lock为止。 我在Kubuntu12.04中运行JavaFX,可能是Kubuntu的bug,我没有机会在另一个操作系统上尝试。 知道吗?

  • 我试图建立一个国际象棋游戏在Python使用tkinter的图形。我创建了一个8x8(行和列)的网格,并将瓷砖放在那里(这是一种按钮)。这一切都很好,直到你用棋子填满整行,然后整行消失。我不知道为什么。 当填充整行时,除了一个:https://gyazo.com/865aed481e4a84c5e9e8918695410006 填充整行时:https://gyazo.com/acf48c97903

  • 我对场景构建器有意见。我想在按钮上添加ContextMenu。当我在按钮上拖放ContextMenu时,它工作得很好(它出现在Hierarchy选项卡中)。但是当我点击Hierarchy选项卡中预定义的MenuItem(在ContextMenu下)时,Scence Builder会冻结,我不得不关闭它。 谁能帮我一下吗?我知道我可以在Java代码中创建一个ContextMenu,但我想在Scene

  • 这似乎是件很简单的事情,但我在任何地方都找不到。我想要一个简单的程序(比如自动热键,但我找不到使用自动热键的方法),当我按下某个键时,它会冻结我的键盘和鼠标(无论我当时按什么键,即使我释放了实际的键/按钮),并将其冻结,直到我再次按下该键(选择的键从未被其他程序视为按下)。 我只是希望这样,如果游戏希望我按住一些按钮,我可以按下按钮,按下指定的键,松手,然后在我应该松开按钮的时候再次按下键。

  • 我是Swing的新手,所以这似乎是一个非常天真的问题。 我有一个JFrame,它显示一个初始语句和两个单选按钮。RadioButton1表示接受,RadioButton2表示拒绝。如果用户选择接受,程序将继续。因此,我为Accept创建了一个ActionListener,以便我的其余代码都在这个ActionListener中。然而,只要用户按下Accept,GUI就会冻结。按Reject键只是程序