如何在TopLevel窗口中的函数调用后获取标签?

问题描述 投票:0回答:3

我正在尝试在python中构建一个顶层窗口,其中有一个名为“text”的标签。它的textvariable称为“v”。如您所见,在dialogBox()中有3个函数调用。我希望程序做的是让标签“text”显示短语“Event one”,等待一秒钟,显示短语“Event 2”,等待一秒钟,然后显示短语“Event 3”。而不是这样做,顶层窗口打开,仅显示“事件三”。

我怀疑这是一个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()
python tkinter lambda
3个回答
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()

唯一真正的变化是使用来自afterevent1()方法来调用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()粗鲁地告诉GUI,“停止你正在做的一切,现在就为我做这件事!”这还允许您查看event1,event2,event3消息。但after()真的是更好,更好的方法来做到这一点。


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()

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()
© www.soinside.com 2019 - 2024. All rights reserved.