问题描述
作为一个刚接触编程的人,我经常发现自己遇到错误和问题,在寻找答案和解决方案的过程中,我很少弄清楚为什么会这样.这一次,它使用 Python 2.7 上的 Tkinter.手头的问题是每次按下我创建的提交"按钮时,GUI 都会冻结.研究告诉我这个问题是因为没有回调来允许程序到达主循环.我面临的问题是与 GUI 一起运行的程序是计时器上永无止境的自动化循环.我也在这个网站上搜索过,但是,像往常一样,我只得到这样做是因为我说它有效"之类的答案.作为一个真正感兴趣并试图越来越深入地了解编程这个光辉黑洞的人,解释为什么需要那样做以及你是如何得出这个结论的,对我来说会有很大帮助.我完全理解编程是一种如此广泛但又如此特殊的事物,以至于解释变得不同并且有时会产生偏见,但我发现很难以其他方式学习.
As someone who is new to programming, I constantly find myself running into errors and issues and, while finding answers and solution, I rarely find out why it is that way. This time, it with Tkinter on Python 2.7.The issue at hand is every time the "submit" button I created is pressed, the GUI freezes. Research has told me that the issue is because there is no callback to allow the program to reach the mainloop. The problem i am facing is the program that runs with the GUI is a never ending automation loop on a timer. I've searched on this site as well, but, like usual, I only get answers where it says things like "Do this because I said it works". As someone who is really interested and trying to get deeper and deeper into the glorious black hole that is programming, an explanation of why it needs to be that way and how you came to that conclusion would be a big help to me. I fully understand that programming is one of those things that is so broad, yet so particular, that explanations become different and sometimes bias, but I find it difficult to learn any other way.
到目前为止,我的代码的简化版本如下:(我知道简化代码在这个站点上不是首选,但我没有办法将代码传输到任何其他计算机,而无需全部写下来并在此处输入.我知道你们以后会为此大喊大叫. 所以,为此,我很抱歉.)
The simplified version of my code I have so far is as follows:(I know simplified code is not preferred on this site, but I don't have the means to transfer the code to any other computer without writing it all down and typing it on here. I know you guys will yell at me for it later. So, for that, I am sorry.)
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 编程的信息,而不会说嘿...只是因为我这么说就这样做",并且非常感谢指向一些研究/参考资料的链接.
Also, as I find it hard to discover and clear information on how to GUI program without it saying "Hey... just do this because I said so", and links to some study/reference materials would be greatly appreciated.
与往常一样,我非常感谢整个网站提供的所有帮助以及所有使网站成为这个地方的非常聪明的人.谢谢大家!
As always, I greatly appreciate all of the help that is provided throughout this site and all of the vastly intelligent individuals that make it the place that it is. Thank you all!
推荐答案
您的 Tk GUI 冻结的原因是因为您在 1 个线程上运行了所有内容.mainloop
由 submit
函数调用拖拽,该函数调用必须花费很长时间",因此当您单击 Tk 窗口时,您可能会看到Not Responding"出现在您的 Tk 窗口中按钮.要解决此问题,您需要为 submit
生成一个单独的线程来运行,以便 mainloop
可以继续做它的事情并防止您的 Tk 窗口冻结.
the reason your Tk GUI freezes is because you have everything running on 1 thread. The mainloop
is haulted by the submit
function call which must be taking a "long time", so you probably see "Not Responding" appear in your Tk window when you click the button. To fix this, you need spawn a separate thread for submit
to run in, so that the mainloop
can keep doing it's thing and keep your Tk window from freezing.
这是使用 threading
完成的.不要让按钮直接调用 submit
,而是让按钮调用一个函数,该函数启动一个新线程,然后启动 submit
.然后创建另一个函数来检查 submit
线程的状态.您也可以添加状态栏
this is done using threading
. Instead of your button directly calling submit
, have the button call a function that starts a new thread which then starts submit
. Then create another functions which checks on the status of the submit
thread. You can add a status bar too
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()
这篇关于单击按钮时,如何阻止 Tkinter GUI 冻结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!