【问题标题】:Python3, Tkinter GUI crashes and button remain clickedPython3,Tkinter GUI 崩溃并且按钮保持点击状态
【发布时间】:2018-01-23 10:07:04
【问题描述】:

我制作了一个包含无限循环的代码,并制作了一个带有开始按钮的 Tkinter 界面。

当我点击按钮时,窗口认为 GUI 已经崩溃——即使它在后台工作——并且按钮仍然被点击。

-如何取消单击按钮?

-再次单击时如何使相同的 Tkinter 窗口开始一个新循环?使窗口保持响应。

示例代码:

import time
from tkinter import *

def do():
    while x > 0:
        try:
            x = 1
            x += 1
            return x
        except:
            time.sleep(x)
            x = 0

window = Tk()

Button(text='Start',width=30, command=do).grid(row=0, column=0)

mainloop()

except 有异常错误被认为发生的地方,

为了添加一些上下文,我将它与 selenium 库一起使用

【问题讨论】:

    标签: python user-interface tkinter


    【解决方案1】:

    我在这里看到了几个问题:

    1.) do() 前面没有def

    2.) expect 应该是 except

    3.) 您的while 循环阻塞了您的程序流程。相反,您应该使用Tk().after(wait_time, method)

    话虽如此,我假设您想在按下按钮后进行计数。

    点击按钮后从 0 开始计数。 再次单击该按钮时,它将停止打印count 并重置它:

    from tkinter import *
    
    class App:
    
        def __init__(self):
            self.root = Tk()
    
            self.count = 0
            self.do_count = False
    
            self.button = Button(self.root, text="Click me.", command=self.do)
            self.button.pack()
    
            self.root.mainloop()
    
        def do(self):
            self.do_count = not self.do_count
            if not self.do_count:
                self.count = 0
            self.update()
    
        def update(self):
            if self.do_count:
                print(self.count)
                self.count += 1
                self.root.after(1000, self.update)
    
    
    app = App()
    

    【讨论】:

    • 谢谢,我纠正了前几个错误,但我仍在努力掌握我的第三个错误,我是新手,所以需要一段时间,我会查找 pack() 和after() 并在我将它们实施到我的代码中后回复你,如果你对这个问题的兴趣一直存在的话。
    • pack() 只是将小部件放置在 tkinter 指定的下一个默认位置。在我的示例中,after() 等待 1000 毫秒(1 秒),然后再次调用 update() 方法(本身)。
    • after() 只是确保该方法经常被调用。 while 循环使程序挂起,因为它永远无法退出该循环,因此程序无法继续执行。
    • 试过了,它在某种程度上起作用了我让按钮命令调用另一个函数,该函数调用我想要完成的函数。带有while循环的那个,然后又崩溃了,我想无限的for或if循环会导致同样的问题,不是吗?
    • @T.Galisnky 是的。任何“无限”循环都是阻塞的。 (除非它在它自己的单独线程中,但那是另一回事。)因此,它不会继续到程序的其余部分。 Tkinter 在后台处理它的主循环中的事情。如果您调用的函数阻止程序返回到它的主循环(如 while 循环),那么程序将因为无法继续执行而崩溃。
    【解决方案2】:

    这行得通:

    import threading
    import time
    from tkinter import *
    
    def clicked():
        threading.Thread(target=do).start()
    
    def do():
        while x > 0:
            try:
                x = 1
                x += 1
                return x
            except:
                time.sleep(x)
                x = 0
    
    window = Tk()
    
    Button(text='Start',width=30, command=clicked).grid(row=0, column=0)
    
    mainloop()
    

    使用风险自负,因为它本身不会让你打破循环,如果我找到方法会更新

    编辑:

    最简单的解决方案是创建守护线程,如果您关闭了 GUI,这有助于关闭您的代码,您可以通过编辑上面代码中的一行来做到这一点:

    threading.Thread(target=do, daemon=True).start()
    

    【讨论】:

      猜你喜欢
      • 2018-07-27
      • 2015-10-02
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 2013-12-31
      • 2013-08-22
      • 1970-01-01
      • 2017-06-15
      相关资源
      最近更新 更多