Python 在tkinter中使用.config
这里是初学者 在一个简单的倒计时应用程序上更新标签时遇到困难, 有人能解释为什么标签在循环中不更新吗Python 在tkinter中使用.config,python,user-interface,tkinter,Python,User Interface,Tkinter,这里是初学者 在一个简单的倒计时应用程序上更新标签时遇到困难, 有人能解释为什么标签在循环中不更新吗 import time import tkinter as tk root = tk.Tk() root.geometry('150x100') seconds_inp = tk.Entry(root) global time_label time_label = tk.Label(root, text = '00', font = 20) start_button = tk.Button(
import time
import tkinter as tk
root = tk.Tk()
root.geometry('150x100')
seconds_inp = tk.Entry(root)
global time_label
time_label = tk.Label(root, text = '00', font = 20)
start_button = tk.Button(root, text = 'start', command = lambda: countdown_clock(int(seconds_inp.get())))
def countdown_clock(seconds):
while True:
seconds = seconds - 1
time.sleep(1)
time_label.config(text = seconds)
print(seconds)
if seconds == 0:
time_label.config(text = 'time!')
break
time_label.grid(row = 1, column = 0)
start_button.grid(row = 2, column = 0)
seconds_inp.grid(row = 3, column = 0)
root.mainloop()
在之后使用
,而不是在
和等待时使用。而且,你的时钟一开始就减去一秒钟。将减去的值发送到下一个调用。如果您要做的就是将每个小部件粘贴到下一个行中的一个列中,那么您不必在网格()
中指定,您只需确保以正确的顺序调用小部件上的网格。如果添加更多列,则规则将更改回您的操作方式
import time
import tkinter as tk
root = tk.Tk()
root.geometry('150x100')
def countdown_clock(s, t):
if not s:
t.configure(text='time!')
return
t.configure(text=s)
root.after(1000, lambda: countdown_clock(s-1, t))
time_lbl = tk.Label(root, text='00', font=20)
time_lbl.grid()
start_btn = tk.Button(root, text='start', command=lambda: countdown_clock(int(seconds_ent.get()), time_lbl))
start_btn.grid()
seconds_ent = tk.Entry(root)
seconds_ent.grid()
root.mainloop()
在
之后使用,而不是在
和
等待时使用。而且,你的时钟一开始就减去一秒钟。将减去的值发送到下一个调用。如果您要做的就是将每个小部件粘贴到下一个行中的一个列中,那么您不必在网格()
中指定,您只需确保以正确的顺序调用小部件上的网格。如果添加更多列,则规则将更改回您的操作方式
import time
import tkinter as tk
root = tk.Tk()
root.geometry('150x100')
def countdown_clock(s, t):
if not s:
t.configure(text='time!')
return
t.configure(text=s)
root.after(1000, lambda: countdown_clock(s-1, t))
time_lbl = tk.Label(root, text='00', font=20)
time_lbl.grid()
start_btn = tk.Button(root, text='start', command=lambda: countdown_clock(int(seconds_ent.get()), time_lbl))
start_btn.grid()
seconds_ent = tk.Entry(root)
seconds_ent.grid()
root.mainloop()
while
循环会导致windows在一段时间后没有响应,因此最好的方法是消除这种情况,并使用内置的after()
方法
以下是一个工作示例:
import time
import tkinter as tk
root = tk.Tk()
root.geometry('150x100')
seconds_inp = tk.Entry(root)
time_label = tk.Label(root, text='00', font=20)
start_button = tk.Button(
root, text='start', command=lambda: countdown_clock(int(seconds_inp.get())))
def countdown_clock(seconds):
seconds = seconds - 1
time_label.config(text=seconds)
call = root.after(1000, lambda: countdown_clock(seconds))
if seconds == 0:
root.after_cancel(call)
time_label.config(text='Time up!!')
print(seconds)
time_label.grid(row=1, column=0)
start_button.grid(row=2, column=0)
seconds_inp.grid(row=3, column=0)
root.mainloop()
我所做的只是,我删除了while
,因为它会中断mainloop()
方法,所以我使用after()
方法连续调用函数,直到second
达到0,然后取消after()
并最终更新标签。我删除了函数外部的global
,因为在函数外部调用这些函数是毫无意义的
希望这消除了你的疑虑
欢呼声,而
循环会导致windows在一段时间后没有响应,因此最好的方法是消除这种情况,并使用内置的after()
方法
以下是一个工作示例:
import time
import tkinter as tk
root = tk.Tk()
root.geometry('150x100')
seconds_inp = tk.Entry(root)
time_label = tk.Label(root, text='00', font=20)
start_button = tk.Button(
root, text='start', command=lambda: countdown_clock(int(seconds_inp.get())))
def countdown_clock(seconds):
seconds = seconds - 1
time_label.config(text=seconds)
call = root.after(1000, lambda: countdown_clock(seconds))
if seconds == 0:
root.after_cancel(call)
time_label.config(text='Time up!!')
print(seconds)
time_label.grid(row=1, column=0)
start_button.grid(row=2, column=0)
seconds_inp.grid(row=3, column=0)
root.mainloop()
我所做的只是,我删除了while
,因为它会中断mainloop()
方法,所以我使用after()
方法连续调用函数,直到second
达到0,然后取消after()
并最终更新标签。我删除了函数外部的global
,因为在函数外部调用这些函数是毫无意义的
希望这消除了你的疑虑
干杯用户界面无法更新,因为您被困在使用时间的循环中。睡眠
。看看。(…)
之后的时间。sleep()
正在干扰tkinter的mainloop()
。您应该能够通过使用通用小部件方法(在调用config()
之后)来更新标签。另一种选择是使用universalafter()
widget方法代替time.sleep()
,因为它不会产生干扰。现在,当Michael给出了下面的有效答案时,正如另一个答案一样,不建议在GUI中使用while循环(特别是在您刚开始时),'因为它经常阻止GUI更新,因为它没有到达mainloop
。在这些情况下,使用@martineau建议的update_idletasks()
。即使在您自己的代码中,只要在time\u label.config(text=seconds)
行之后添加time\u label.update\u idletasks()
,就可以解决GUI更新中的问题。但是,正如michael所说,要小心一些事情,比如在计时器启动之前减去一秒钟,以及网格安排。@PSSolanki然而,使用update\u idletaks()
最终会导致窗口没有响应,即使时间过了,GUI也跟不上进度,而且我注意到,这也会导致标签写得太多(虽然我不知道为什么)@PSSolanki-hmmmm,我注意到update()
比update\u idletasks()
对我来说效果更好,如果OP能标记一个答案,关闭QT,用户界面无法更新,因为你使用time.sleep
卡在循环中。看看。(…)
之后的时间。sleep()
正在干扰tkinter的mainloop()
。您应该能够通过使用通用小部件方法(在调用config()
之后)来更新标签。另一种选择是使用universalafter()
widget方法代替time.sleep()
,因为它不会产生干扰。现在,当Michael给出了下面的有效答案时,正如另一个答案一样,不建议在GUI中使用while循环(特别是在您刚开始时),'因为它经常阻止GUI更新,因为它没有到达mainloop
。在这些情况下,使用@martineau建议的update_idletasks()
。即使在您自己的代码中,只要在time\u label.config(text=seconds)
行之后添加time\u label.update\u idletasks()
,就可以解决GUI更新中的问题。但是,正如michael所说,要小心一些事情,比如在计时器启动之前减去一秒钟,以及网格安排。@PSSolanki然而,使用update\u idletaks()
最终会导致窗口没有响应,即使时间过了,GUI也跟不上进度,而且我注意到,这也会导致标签写得太多(虽然我不知道为什么)@PSSolanki-hmmmm,我注意到update()
比update\u idletasks()
对我来说效果更好,如果OP能给出答案,请关闭Q