#python-3.x #tkinter
#python-3.x #tkinter
Вопрос:
У меня есть функция, которая запускается только после нажатия кнопки tkinter. Внутри функции есть цикл for, который выполняет итерацию по набору данных, который я хотел бы динамически отображать через метку tkinter. То есть будет только 1 метка tkinter, и ее значение будет постоянно меняться между итерациями в цикле for .
Самое близкое, что я получил, это то, что на каждой итерации будет создаваться новая метка, и она продолжает расширяться внизу, что не то, что я ищу. Кто-нибудь может посоветовать мне какое-либо возможное направление, которое я могу предпринять?
Ниже приведена структура кодов, которые я пробовал.
root = tk.Tk()
order_json = tk.StringVar()
def update_label(order):
order_json.set(order)
root.update()
def order_func():
for i in range(len(dataset)):
data_to_display = dataset[i]
label = tk.Label(root, textvariable=order_json)
label.pack()
update_label(order)
таким образом, вместо одной метки, которая постоянно обновляется, каждая итерация создает новую метку под старой, и она просто продолжает расширяться.
Я был бы признателен, если кто-нибудь сможет помочь мне. Спасибо.
Ответ №1:
Мы не можем использовать for
while
циклы or для обновления в реальном времени в графическом интерфейсе tkinter, это потому, что tkinter уже находится в режиме a, из- mainloop
за чего использование for
цикла or while
заставляет графический интерфейс перестать отвечать до окончания цикла, но если for
цикл или while
цикл невелики и заканчиваются, мы можем использовать их, как если бы мы хотели 10метки во фрейме, которые мы можем просто использовать
for i in range(10):
Label(root, text='Label %s' %i).pack()
Но если вам нужно время от времени видеть изменения динамически, в вашем случае обновите метку, чтобы увидеть набор данных. Для этих целей мы используем after(ms, callback, args)
. Также не используйте sleep
вместо этого use after(ms)
без какого-либо обратного вызова.
Допустим, я хочу увидеть подсчет. В котором я просто хочу, чтобы метка обновлялась каждые 0,5 секунды, я могу использовать что-то вроде этого.
Пример
import tkinter as tk
root = tk.Tk()
Label = tk.Label(root, text=1, font=('', 20))
Label.pack()
def update(count=1):
Label['text'] = count
# 500ms , calling the same function again and again.
root.after(500, update, count 1)
update()
root.mainloop()
Теперь ответьте на вашу проблему
Поскольку я не знаю, что dataset
это такое, я просто беру список от 1 до 50.
Код:
import tkinter as tk
root = tk.Tk()
root.geometry('200x200')
order_json = tk.StringVar()
dataset = [i for i in range(50)]
label = tk.Label(root, textvariable=order_json, font=('', 20))
label.pack()
count = 1
def order_func():
global dataset, count
if count>=len(dataset): return # This will exit the function when done
order_json.set(dataset[count]) # This will update the label
count = 1
root.after(100, order_func) # This will recall the callback function
tk.Button(root, text='Play', command=order_func).pack()
tk.mainloop()