当我点击我的按钮时,如何阻止我的Tkinter GUI冻结?

时间:2016-12-29 00:57:51

标签: python-2.7 user-interface tkinter

作为对编程不熟悉的人,我经常发现自己遇到了错误和问题,在找到答案和解决方案时,我很少发现为什么会这样。这一次,它与Python 2.7上的Tkinter。 手头的问题是每次提交"按下我创建的按钮,GUI冻结。研究告诉我,问题是因为没有回调允许程序到达主循环。我面临的问题是使用GUI运行的程序是计时器上永无止境的自动化循环。我也在这个网站上搜索过,但是,和往常一样,我只能得到答案,其中包括"这样做,因为我说它有效"。作为一个真正感兴趣并试图深入了解编程的光荣黑洞的人,解释为什么需要这样做以及你如何得出这个结论对我来说将是一个很大的帮助。我完全理解编程是那些广泛而又如此特殊的事情之一,解释变得不同,有时会有偏见,但我发现很难以其他方式学习。

到目前为止我的代码的简化版本如下: (我知道简化代码在这个网站上不是首选,但是我没有办法将代码转移到任何其他计算机而不写下来并在这里输入。我知道你们会对我大喊大叫以后。为此,我很抱歉。)

import os
import time
from datetime import datetime
import shutil
from Tkinter import *

root=Tk()
root.title("Automation")
root.config(bg="black")
root.geometry("500x500")

def submit():
    input=e1.get()
    #the input is a limit set for a variable in the timer that when
    #it hits that limit, it jumps to the 400 lines of code
    def Timer():
        <timer code>
    <400 lines of code that has been tested to work 100%>
    Timer()

b1=Button(root, command=submit)
button.grid(row=0, column =0)
e1=Entry(root, width=50)
e1.grid(row=0, column=1)

mainloop()

此外,我发现很难发现和清除有关如何使用GUI程序的信息,而不是说#34;嘿......只是这样做,因为我这么说&#34;,并链接到一些研究/参考资料非常感谢。

与往常一样,我非常感谢本网站提供的所有帮助以及所有非常聪明的人,使其成为现实。谢谢大家!

1 个答案:

答案 0 :(得分:3)

您的Tk GUI冻结的原因是因为您在1个线程上运行了所有内容。 mainloop函数调用submitsubmit函数调用,必须花费很长时间,因此当您单击按钮时,您可能会在Tk窗口中看到“无响应”。要解决这个问题,你需要为mainloop生成一个单独的线程来运行,这样threading可以继续做它并使你的Tk窗口不会冻结。

这是使用submit完成的。而不是按钮直接调用submit,让按钮调用一个函数,启动一个新的线程,然后启动submit。然后创建另一个函数来检查import os import time from datetime import datetime import shutil import threading from Tkinter import * import ttk def submit(): time.sleep(5) # put your stuff here def start_submit_thread(event): global submit_thread submit_thread = threading.Thread(target=submit) submit_thread.daemon = True progressbar.start() submit_thread.start() root.after(20, check_submit_thread) def check_submit_thread(): if submit_thread.is_alive(): root.after(20, check_submit_thread) else: progressbar.stop() root = Tk() frame = ttk.Frame(root) frame.pack() progressbar = ttk.Progressbar(frame, mode='indeterminate') progressbar.grid(column=1, row=0, sticky=W) ttk.Button(frame, text="Check", command=lambda:start_submit_thread(None)).grid(column=0, row=1,sticky=E) root.mainloop() 线程的状态。您也可以添加状态栏

multiDexEnabled true