tkinter: progress list not updating

1.3k Views Asked by At

I have great difficulty boiling down my problem into a fundamental one, so my apologies if this is already treated in another question.

My problem lies in providing progress feedback to the user. The basic system is used to import files, analyze them (with an external function) and in the end produce an output file. During the analysis i would like to let the user know which files have already been analysed.

The GUI consist of two listboxes: the left one shows the files chosen for analysis and the right one should show the files which have been analyzed. The button in the bottom starts the analysis.

The problem is that the progress list only updates after the for loop is completed and not in between.

Help is much appreciated as i have been stuck quite a while now.

The main file:

from Tkinter import *
from ext_function import Xfunct
import tkFileDialog
import time

root=Tk()
width=3;
files=Frame(root, relief=GROOVE,borderwidth=width)
progress=Frame(root, relief=GROOVE,borderwidth=width)
analysis=Frame(root)

global fl_paths
global fl_names
fl_paths=[]
fl_names=[]

#################  Functions #################

def f_load_files():
    temp = root.tk.splitlist(tkFileDialog.askopenfilenames(parent=root,title='Select files'))
    temp_list=list(temp)

    for i in range(len(temp_list)):
        fl_names.append(temp_list[i].split('/')[-1])
        fl_paths.append(temp_list[i])
        file_list.insert(END, fl_names[-1])

def f_run():
    for i in range(len(fl_names)):
        Xfunct(i) #call the function
        prog_list.insert(END,fl_names[i])#update the list in the progress box           

#################  File selection frame #################
files_name=Label(files,text='File selection:')
files_name.grid(column=0,row=0)
file_list=Listbox(files)
file_list.grid(column=0, row=1, columnspan=2, rowspan=4,pady=3, padx=10)
load_files=Button(files,text='Load files',command=f_load_files)
load_files.grid(column=0,row=5, padx=3, pady=6)

################# Progress #################
progress_name=Label(progress,text='Done:')
progress_name.grid(column=0,row=0, columnspan=3)
prog_list=Listbox(progress)
prog_list.grid(column=0, row=1, columnspan=3, padx=10)

################# Analysis #################
start_analysis=Button(analysis,text='Make Analysis',command=f_run)
start_analysis.grid(column=4, row=1, rowspan=10, padx=10)

################# Align frames #################
files.grid(row=0, column=0, padx=10, pady=10, sticky=N+S+W+E)
progress.grid(row=0, column=1, pady=10, padx=10, sticky=N+S+W+E)
analysis.grid(row=2,column=0, columnspan=2, padx=10, pady=10)

mainloop()

The external function called Xfunct, located in a file called ext_funct.py:

def Xfunct(i):
    import time

    print i
    time.sleep(3)
1

There are 1 best solutions below

2
On BEST ANSWER

You should use the update() method on your window. Normally tkinter updates the window in mainloop(). It re-draws the window content very fast (many, many times per second). When you now call f_run() the mainloop() is interrupted until the function is completed. Everywhere you want to re-draw the window content, type root.update() into the code. For example:

for i in range(len(fl_names)):
    Xfunct(i)
    root.update()
    prog_list...

Or you should use

update_idletasks()

As described in the comment(s)