tkinter:循环进行循环时不更改标签值,仅使最终值无效

时间:2019-04-11 11:16:08

标签: python user-interface tkinter

我已经为某些文件处理python脚本创建了一个tkinter UI。当我们选择目录时,它将返回目录中的文件,然后它将使用for循环获取每个文件,并且将显示“已处理文件”以进行覆盖迭代。因此,已处理文件数必须从0更改为目录中的文件总数。

import os
import time
from tkinter import *
from tkinter import filedialog
import tkinter as tk
root = Tk()
root.title("Demo")
root.geometry('550x300')
root.resizable(width=False, height=False)
def start(userInput,):
    e1.configure(text=userInput.get())
    print(userInput.get())
    ll.destroy()
    e1.destroy()
    browse_btn.destroy()
    st_btn.destroy()
    folder_path = userInput.get()
    path = folder_path
    TEST_IMAGE_PATHS = [f for f in os.listdir(path) if f.endswith('.jpg')]
    # print(TEST_IMAGE_PATHS)
    Total_No_Files = len(TEST_IMAGE_PATHS)
    II_l2_prompt="Total number of files   "
    II_l2 = Label(root, text=II_l2_prompt, width=22, font=("Arial", 11))
    II_l2.place(x=30, y=160, height=25)

    II_l3_prompt = str(Total_No_Files)
    II_l3 = Label(root, text=II_l3_prompt, width=len(II_l3_prompt), font=("Arial", 11))
    II_l3.place(x=240, y=160, height=25)
    II_l4_prompt="Processed files         "
    II_l4 = Label(root, text=II_l4_prompt, width=22, font=("Arial", 11))
    II_l4.place(x=30, y=210, height=25)
    my_string_var = tk.StringVar()
    II_l5_prompt=0
    my_string_var.set(II_l5_prompt)
    II_l5 = Label(root, textvariable=my_string_var, width=len(str(my_string_var)), font=("Arial", 11))
    II_l5.place(x=240, y=210, height=25)

    for e in TEST_IMAGE_PATHS:
        II_l5_prompt += 1
        # time.sleep(2)

        my_string_var.set(II_l5_prompt)

def browse(userInput):

    File_path = filedialog.askdirectory(title='Select Folder')
    if File_path:
        File_name = os.path.basename(File_path)
        # print(File_name)
        e1.delete(0, "end")  # delete all the text in the entry
        e1.insert(0, File_path)
        e1.config(fg='black')

ll = Label(root, text="Path", font=("Arial", 12))
ll.place(x=30, y=110, height=25, width=39)

userInput = StringVar()

e1 = Entry(root,bd=1, textvariable=userInput,width=35, font=("Arial", 12))
e1.insert(0, 'Choose')
e1.config(fg='grey')
e1.bind('<Return>', (lambda event: browse(userInput)))
e1.place(x=80, y=110, height=25)

browse_btn = Button(root, text='Browse',width="10", height=5, bd=0, bg="grey",fg='white',  command=(lambda: browse(userInput)))
browse_btn.place(x=420, y=105, height=35)
st_btn = Button(root, text='Start',width="10", height=5, bd=0,bg="grey",fg='white',  command=(lambda: start(userInput,)))
st_btn.place(x=150, y=200, height=35)
root.mainloop()

但是,此处的“已处理文件”字段将返回最后一个文件号,而不是将标签从第一个文件号更改为目录中的最后一个文件。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

该窗口将在空闲时更新。在这里它将把对GUI的所有更改排队,直到完成所有处理,然后在for循环退出后更新窗口。因此,您只会看到最后一个状态。

您可以强制root用root.update()root.update_idletasks()更新:

root.update()           # Update GUI after removing labels & buttons
for e in TEST_IMAGE_PATHS:
    II_l5_prompt += 1
    my_string_var.set(II_l5_prompt)
    root.update_idletasks() # Update GUI after changing II_l5_prompt
    time.sleep(2)

我不确定root.update_idletasks()为何在for循环前使用时不起作用,但是root.update()有用。