我有一个可以拉出并显示几个更新值的程序。我有一个按钮,可以手动重新加载必要的信息。我的最终目标是要有一个文本字段,我可以在其中键入一个值,并使程序每x
秒重新加载一次。我的问题出在设置新的循环间隔值。
以下是我遇到的问题的基本示例:
import tkinter as tk
import datetime
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
reloadTimer=tk.Entry(root)
reloadTimer.pack(side=tk.LEFT)
reloadTimer.insert(10,10)
def masterReload():
print("LOADING " + str(datetime.datetime.now()))
parent.after(int(reloadTimer.get())*1000, masterReload)
masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())
masterReloadButton.pack()
masterReload()
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack()
root.mainloop()
我的问题是,每当我按下masterReloadButton
时,都会启动一个新的“重新加载循环”。
例如:
这是我按下任何按钮之前的输出。循环间隔约为10秒。
这是我按masterReloadButton
(大约5秒钟进入循环)后的输出。现在有两个循环同时发生,偏移量约为5秒。它确实捕获了新的循环值,但也完全生成了一个新的循环。
我需要“设置”按钮,因为否则新的计时器值仅在重新加载时才检索。如果有人输入非常大的数字,则程序将花费很长时间才能接受新值。
在我看来,每次我按下按钮时,都会创建一个新的masterReload()
流程。我需要每次都破坏该过程,或者重新组织我的代码以免发生这种情况,但是我不确定该怎么做。
谢谢。
答案 0 :(得分:1)
防止出现此问题的一种方法是在按下按钮后将其禁用。
我们可以启动master_reload
循环并使用lambda
表达式同时禁用按钮。
这是您的代码在第一次按下后被禁用的按钮,被清除了一点。
更新:现在在循环之后立即更新,而不是等待上一个循环结束。
import tkinter as tk
import datetime
class MainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.reload_timer = tk.Entry(self)
self.reload_timer.pack(side='left')
self.reload_timer.insert(10, 10)
self.active_after = None
self.time_tracker = None
self.btn = tk.Button(self, text='Set', command=self.set_time_tracker)
self.btn.pack()
def master_reload(self):
print("LOADING {}".format(datetime.datetime.now()))
self.active_after = self.after(self.time_tracker*1000, self.master_reload)
def set_time_tracker(self):
x = self.reload_timer.get()
if x.isdigit():
if int(x) > 0:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
self.time_tracker = int(x)
self.master_reload()
else:
self.time_tracker = int(x)
self.master_reload()
else:
self.after_cancel(self.active_after)
self.active_after = None
else:
if self.active_after is not None:
self.after_cancel(self.active_after)
self.active_after = None
if __name__ == "__main__":
MainApplication().mainloop()
这里的好处是您可以随时更改时间,而不会引起重复的循环,甚至可以通过键入零0
或任何字母并按set来停止循环。
答案 1 :(得分:1)
问题:我希望按钮能够强制设置新的间隔
新间隔是使用
计算的int(reloadTimer.get())*1000
因此,无需单击Button
。
要强制设置新的间隔,您必须取消当前正在运行的reload_after()
循环并开始一个新的循环。
使用两个功能,masterReload()
,点击reload_after()
即可取消/启动 Button
。
另一个reload_after()
通过循环显示值。
取消
.after(...
上的Button
单击:
self.after_id = None
def masterReload():
# New intervall
# Cancel previous reload_after() loop
if self.after_id:
self.after_cancel(self.after_id)
self.after_id = None
# Start new reload_after() loop
parent.after(0, reload_after)
def reload_after():
print("LOADING " + str(datetime.datetime.now()))
self.after_id = parent.after(int(reloadTimer.get())*1000, reload_after)
masterReloadButton = tk.Button(root, text='Set', command=lambda:masterReload())