我试图在python中构建一个顶层窗口,其中有一个名为" text"的标签。它的textvariable被称为" v"。如您所见,在dialogBox()中有3个函数调用。我希望程序做的是标签" text"显示短语"事件一",等待一秒钟,显示短语"事件二",等待一秒钟,然后显示短语"事件三"。而不是这样做,顶层窗口打开,仅显示"事件三"。
我怀疑这是一个lambda问题,但我仍然不确定如何在Tkinter中使用它。
from tkinter import*
import time
def event1():
v.set("Event one")
def event2():
v.set("Event two")
def event3():
v.set("Event three")
def dialogueBox():
top = Toplevel()
global v
top.minsize(400,0)
top.maxsize(700,300)
top.title("Toplevel test")
v = StringVar()
text = Label(top,textvariable = v)
text.pack()
event1()
time.sleep(1)
event2()
time.sleep(1)
event3()
root = Tk()
email = StringVar()
password = StringVar()
title = Label(root,text="Root window",font = 11)
title.pack()
label1 = Label(root,text = "Username")
label1.pack()
field1 = Entry(root,textvariable = email)
field1.pack()
label2 = Label(root,text = "Password")
label2.pack()
field2 = Entry(root,show = "*",textvariable = password)
field2.pack()
button = Button(root,text = "Get data",command = dialogueBox)
button.pack()
root.mainloop()
答案 0 :(得分:1)
你非常接近,但你最好的选择是使用after()
方法。
这是修改过的代码,添加了评论:
from tkinter import*
import time
def event1():
v.set("Event one")
root.after(1000, event2) # NEW
def event2():
v.set("Event two")
root.after(1000, event3) # NEW
def event3():
v.set("Event three")
def dialogueBox():
top = Toplevel()
global v
top.minsize(400,0)
top.maxsize(700,300)
top.title("Toplevel test")
v = StringVar()
text = Label(top,textvariable = v)
text.pack()
event1()
#time.sleep(1)
#event2()
#time.sleep(1)
#event3()
root = Tk()
email = StringVar()
password = StringVar()
title = Label(root,text="Root window",font = 11)
title.pack()
label1 = Label(root,text = "Username")
label1.pack()
field1 = Entry(root,textvariable = email)
field1.pack()
label2 = Label(root,text = "Password")
label2.pack()
field2 = Entry(root,show = "*",textvariable = password)
field2.pack()
button = Button(root,text = "Get data",command = dialogueBox)
button.pack()
root.mainloop()
唯一真正的变化是使用after
中的event1()
方法来呼叫event2()
,以及event2()
来呼叫event3()
。通过这些after()
来电,dialogueBox()
中的最后4行会消失。
发生了什么事? Tkinter是一个GUI,事件驱动的系统。它不喜欢坐在那里等待任何事情。当您正在睡觉时,会浪费资源,并且GUI无法刷新和更新自身。通过使用after()
方法,GUI可以继续做它最擅长的事情:等待事件和输入。 after()
方法会安排稍后发生的事件。到那时,事件就会得到处理。 after()
的第一个arg是以ms(毫秒)为单位的时间延迟。第二个arg是一个函数名,在指定的时间延迟后调用。
现在,我说after()
是你最好的选择,但还有另一种方法可以做到这一点,尽管不那么礼貌。"您可以向.update()
添加dialogueBox()
方法调用,如下所示:
def dialogueBox():
top = Toplevel()
global v
top.minsize(400,0)
top.maxsize(700,300)
top.title("Toplevel test")
v = StringVar()
text = Label(top,textvariable = v)
text.pack()
event1()
text.update() # NEW -- RUDE!
time.sleep(1)
event2()
text.update() # NEW -- RUDE!
time.sleep(1)
event3()
.update()
电话粗暴地告诉图形用户界面,"停止您正在做的所有事情并立即为我做这件事!"这还允许您查看event1,event2,event3消息。但是after()
实际上是更好,更合适的方法。
答案 1 :(得分:1)
在event1()
中使用root.after(1000, event2)
并在event2
event1
您必须从sleep()
event2()
和event3()
dialog_box()
个功能
import tkinter as tk
# --- functions ---
def event1():
v.set("Event one")
root.after(1000, event2) # run event2 after 1000ms (1s)
def event2():
v.set("Event two")
root.after(1000, event3) # run event3 after 1000ms (1s)
def event3():
v.set("Event three")
root.after(1000, close_it) # run close_it after 1000ms (1s)
def close_it():
top.destroy() # close TopLevel window
def dialogue_box():
global v
global top
top = tk.Toplevel()
top.minsize(400,0)
top.maxsize(700,300)
top.title("Toplevel test")
v = tk.StringVar()
text = tk.Label(top, textvariable=v)
text.pack()
event1() # run event1 at once
# --- main ---
root = tk.Tk()
email = tk.StringVar()
password = tk.StringVar()
title = tk.Label(root, text="Root window", font=11)
title.pack()
label1 = tk.Label(root, text="Username")
label1.pack()
field1 = tk.Entry(root, textvariable=email)
field1.pack()
label2 = tk.Label(root, text="Password")
label2.pack()
field2 = tk.Entry(root, show="*", textvariable=password)
field2.pack()
button = tk.Button(root, text="Get data", command=dialogue_box)
button.pack()
root.mainloop()
答案 2 :(得分:0)
在此处查看演示,也可以使用itertools“show off”
from tkinter import *
import time
from itertools import cycle
label_iter = cycle(('Event One', 'Event Two', 'Event Three'))
def change_label():
v.set(next(label_iter))
root.after(1000, change_label)
def dialogueBox():
top = Toplevel()
global v
top.minsize(400,0)
top.maxsize(700,300)
top.title("Toplevel test")
v = StringVar()
text = Label(top,textvariable = v)
text.pack()
root.after(1000, change_label)
root = Tk()
email = StringVar()
password = StringVar()
title = Label(root,text="Root window",font = 11)
title.pack()
label1 = Label(root,text = "Username")
label1.pack()
field1 = Entry(root,textvariable = email)
field1.pack()
label2 = Label(root,text = "Password")
label2.pack()
field2 = Entry(root,show = "*",textvariable = password)
field2.pack()
button = Button(root,text = "Get data",command = dialogueBox)
button.pack()
root.mainloop()