#python #user-interface #tkinter
#python #пользовательский интерфейс #tkinter
Вопрос:
Я создал пользовательский интерфейс tkinter для некоторого скрипта python для обработки файлов. Когда мы выбираем каталог, он возвращает файлы в каталоге, а затем принимает каждый файл с помощью цикла for и отображает «обработанные файлы» для итерации reach. следовательно, количество обработанных файлов должно быть изменено с 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-го номера файла на последний в каталоге. Как я могу решить эту проблему?
Ответ №1:
Окно будет обновляться, когда оно простаивает. Здесь он будет помещать в очередь все изменения в GUI, пока не будет выполнена вся обработка, а затем обновит окно после завершения цикла for. Поэтому вы увидите только последнее состояние.
Вы можете заставить root обновляться с root.update()
помощью или root.update_idletasks()
:
root.update() # Update GUI after removing labels amp; 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()
работает.