Обновление Tkinter и GUI

#python #tkinter

#python #tkinter

Вопрос:

Текущий код отображает графический интерфейс со списком после добавления всех 3 элементов в список. Можно ли сделать это более интерактивно, т.Е. Графический интерфейс и список отображаются сразу после запуска программы, а затем каждые 1 секунду в список добавляется новый элемент? Я хотел бы иметь решение без параллелизма, потоков и синхронизации.

 from Tkinter import *
import time

master = Tk()
listbox = Listbox(master)
listbox.pack()

for i in range(0,3):
    #Time consuming task which results are placed sequentially in the listbox
    time.sleep(1)
    listbox.insert(END,"Task " str(i) " completed")
    #GUI update needed here
    #.....???

mainloop()
  

Я попытался использовать метод after, как во втором списке, однако поле списка по-прежнему не отображается, пока в него не будут добавлены все элементы.

 from Tkinter import *
import time

def time_consuming_task():
    for i in range(0,3):
        time.sleep(1)
        listbox.insert(END,"Task " str(i) " completed")


master = Tk()
listbox = Listbox(master)
listbox.pack()
master.after(100,time_consuming_task)

mainloop()
  

Ответ №1:

Вы можете просто использовать after() , как показано ниже:

 import Tkinter as tk

master = tk.Tk()

listbox = tk.Listbox(master)
listbox.pack()

def time_consuming_task(n=0):
    if n < 3:
        listbox.insert(tk.END, 'Task {0} completed'.format(n))
        master.after(1000, time_consuming_task, n 1)

master.after(1000, time_consuming_task)
master.mainloop()
  

Ответ №2:

Вам нужно продолжать вызывать after метод, чтобы настроить цепочку вызовов:

 from Tkinter import *

master = Tk()

def time_consuming_task():
    listbox.insert(END, "Task "   str(time_consuming_task.i)   " completed")
    time_consuming_task.i  = 1
    if time_consuming_task.i < 3:
        master.after(1000, time_consuming_task)       

listbox = Listbox(master)
listbox.pack()

time_consuming_task.i = 0
time_consuming_task()
mainloop()
  

Также очень важно, чтобы вы не вызывали sleep() свой код, иначе tkinter зависнет на это время.