【问题标题】:How to create GUI objects one by one with Tkinter如何使用 Tkinter 一个一个地创建 GUI 对象
【发布时间】:2017-06-12 19:28:36
【问题描述】:
我喜欢每秒创建一个对象并一个一个地显示。但是,下面的代码会等待 3 秒并同时显示它们。
from tkinter import *
import time
def create():
for i in range(3):
r4=Radiobutton(root, text="Option 1"+str(i), value=1)
r4.pack( anchor = W )
time.sleep(1)
root = Tk()
create()
root.mainloop()
【问题讨论】:
标签:
python-3.x
time
tkinter
【解决方案1】:
您的代码按原样每秒创建一个您希望的对象,但需要显示此对象,并且在代码流到达mainloop 时显示它们。因此,对于观察者来说,一秒钟后似乎根本没有任何物体。
当然,您可以使用 sleep 和 update,但要注意 - sleeping 会导致窗口无响应,因此如果您的应用程序不是这样,这是可以的选项(老实说 - 根本不可以)绘制并且你在mainloop之外,但如果不是 - 准备一个“冻结”窗口,因为GUI只能在mainloop中重绘自己(一个事件循环,你也可以使用update到达它)而sleep 阻止了这种行为。
但是有一个很好的替代方法,after 方法,看看吧!
还有一个sn-p,所以你可以看到区别:
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
import time
def create_with_sleep():
for _ in range(3):
tk.Radiobutton(frame_for_sleep, text="Sleep Option").pack(anchor='w')
time.sleep(int(time_entry.get()))
root.update()
def create_with_after(times=3):
if times != 0:
tk.Radiobutton(frame_for_after, text="After Option").pack(anchor='w')
times -= 1
root.after(int(time_entry.get()) * 1000, lambda: create_with_after(times))
root = tk.Tk()
test_yard_frame = tk.Frame(root)
frame_for_sleep = tk.Frame(test_yard_frame)
frame_for_after = tk.Frame(test_yard_frame)
test_yard_frame.pack()
frame_for_sleep.pack(side='left')
frame_for_after.pack(side='left')
button_frame = tk.Frame(root)
button_for_sleep = tk.Button(button_frame, text='Create 3 radiobuttons with sleep+update', command=create_with_sleep)
button_for_after = tk.Button(button_frame, text='Create 3 radiobuttons with after', command=create_with_after)
button_frame.pack()
button_for_sleep.pack(side='left')
button_for_after.pack(side='left')
time_label = tk.Label(root, text='Time delay in seconds:')
time_label.pack(fill='x')
time_entry = tk.Entry(root)
time_entry.insert(0, 1)
time_entry.pack(fill='x')
root.mainloop()
延迟 1 秒没有太大区别,但您可以尝试增加延迟以了解为什么 after 选项为 preferable in general。
【解决方案2】:
您可以使用update 对您的对象调用刷新。
在使用时,您必须在 for 循环中添加行 root.update()。
【讨论】:
-
嗨@TimoThund 如果这个答案已经解决了您的问题,请点击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。 当然,没有义务这样做。