如何使用“for”循环和时间延迟替换变量?我正在使用Python和Tkinter

2024-05-15 06:33:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我想为我的一个应用程序中的函数创建一个“加载”窗口。我试过进度条,但我想试试这个,看看它有什么不同。这个想法是在点击按钮时打开一个新窗口。新窗口将有“加载”一词,在短时间延迟后将有一个句号“.”。我已经使用了time.sleep()函数,但它的性能并没有达到应有的水平

我将包括以下代码:

from tkinter import *
from tkinter.ttk import *
from tkinter import Button, Tk, HORIZONTAL
import time

def new_window():
    variable_text = "Loading"
    new_windy = Toplevel(main_window)
    new_windy.title("New_Windy")
    new_windy.geometry("200x200")
    for i in range(10):
        time.sleep(0.3)
        new_windy.update_idletasks()
        variable_text += "."
        label = Label(new_windy, text=variable_text)
        label.pack()

main_window = Tk()
main_window.title("AWESOME_SAUCE")
main_window.geometry('600x600')


button = Button(main_window, text="click_me", command=new_window)
button.pack()

main_window.mainloop()

上面的代码在点击按钮时创建了一个新窗口,但是它没有用附加的句号替换每个迭代中的“loading”一词,而是创建了10个版本的“loading”一词,并用连续的句号堆叠起来


Tags: 函数代码textfromimportnewtimemain
3条回答

我有两种方法可以做到这一点。一种是使用单词和after()的列表,另一种是在句子末尾添加点

方法1: 首先,创建一个包含所有过渡词的列表:

transition = ['Loading','Loading.','Loading..','Loading...','Loading....','Loading.....']

现在,您需要为该列表编制索引,并调用标签上的每个项目,如:

count = 0 #a number to index the list
def new_window():
    new_windy = Toplevel(main_window)
    new_windy.title("New_Windy")
    new_windy.geometry("200x200")

    def change():
        global count #globalize it
        rep = main_window.after(1000,change) #repeat the function every 1 second
        try: #to catch the index error
            label.config(text=transition[count]) #change the text with the list index
        except IndexError: #to get past the error showing up
            main_window.after_cancel(rep) #stop the repetition if no more items left to show
        count += 1 #increase the number by 1 over each repetition
        
    label = Label(new_windy, text=transition[count]) #initially set the text to first element
    label.pack()

    change() #call the function for the first time

transition = ['Loading','Loading.','Loading..','Loading...','Loading....','Loading.....']

方法2: 还有另一种方法,就像您使用+= '.'所做的那样。这将是:

def new_window():
    global text #globalize the main text
    
    new_windy = Toplevel(main_window)
    new_windy.title("New_Windy")
    new_windy.geometry("200x200")

    text = 'Loading' #set the main text 
    def change():
        global text #globalize the new text
        text += '.' #add . over each iteration

        rep = main_window.after(1000,change) #repeat the function every 1 second

        label.config(text=text) #change the text to new text
        if len(text) >= 7+5: #here 7 is the length of word 'Loading' and 5 is the maximum number of dots needed.
            main_window.after_cancel(rep) #stop repeating the function

    label = Label(new_windy, text=text) #set the main text at first
    label.pack()

    change() #call the function initially.

现在来解释一下:

but it is not quite behaving as it should.

这是因为time.sleep()mainloop()发生了混乱,导致了无反应。因此GUI会冻结,因此我们必须使用不冻结GUI的after()。不仅time.sleep(),而且whilefor循环会与mainloop()发生混乱,导致GUI无响应

it just creates 10 versions of the word "loading" stacked on itself with successive numbers of full stops.

这是因为每次运行代码时,都会创建一个带有文本“Loading”的新标签,您要做的是,创建一次文本,然后使用config()在以后更改文本

事实上,您的导入稍后会给您带来麻烦,您正在使用ttk中的小部件过度编写tkinter小部件,因此更改您的导入语句并相应地调整代码,如:

import tkinter as tk
from tkinter import ttk

现在,如果您想要tkinter小部件,请使用tk.Label()或者如果您想要ttk小部件,请使用ttk.Label()等等

使用label.config()编辑已打包的标签

from tkinter import *
from tkinter.ttk import *
from tkinter import Button, Tk, HORIZONTAL
import time

def new_window():
    variable_text = "Loading"
    new_windy = Toplevel(main_window)
    new_windy.title("New_Windy")
    new_windy.geometry("200x200")
    label = Label(new_windy, text=variable_text)
    for i in range(10):
        time.sleep(0.3)
        new_windy.update_idletasks()
        variable_text += "."
        label.config(text=variable_text)
        label.pack()

main_window = Tk()
main_window.title("AWESOME_SAUCE")
main_window.geometry('600x600')


button = Button(main_window, text="click_me", command=new_window)
button.pack()

main_window.mainloop()

根据你的“加载”的要求,当窗口弹出时先显示,然后在某个时候出现“。”之后,我们可以把它看作是两个过程。在第一个中,我们需要打印“加载”,然后打印“.”。为此,我将For循环保持为迭代两次,第二次使用time.sleep()在出现“.”之前提供一些时间

请参考以下修改代码

from tkinter import *
from tkinter.ttk import *
from tkinter import Button, Tk, HORIZONTAL
import time

def new_window():
    variable_text = "Loading"
    new_windy = Toplevel(main_window)
    new_windy.title("New_Windy")
    new_windy.geometry("200x200")
    label = Label(new_windy, text=variable_text)
    for i in range(2):
        new_windy.update_idletasks()
        if i == 1:
            time.sleep(3)
            variable_text += "."
        label.config(text=variable_text)
        label.pack()

main_window = Tk()
main_window.title("AWESOME_SAUCE")
main_window.geometry('600x600')


button = Button(main_window, text="click_me", command=new_window)
button.pack()

main_window.mainloop()

相关问题 更多 >

    热门问题