Output interim results in new window during tkinter mainloop - Threading Output interim results in new window during tkinter mainloop - Threading tkinter tkinter

Output interim results in new window during tkinter mainloop - Threading


Building on @HenryYik answer, which shows the correct approach but throws a RuntimeErrorwhen attempting to click calculate several times in a row:

RuntimeError: threads can only be started once

The following example pops a tk.Toplevel that shows the intermediate results, and allows clicking repeatedly the calculate button. It will spawn as many toplevel windows, showing as many intermediate results.
Each new thread is identified by a unique number; a console output is printed when a thread is done.

The close button on the Toplevel becomes active when the calculation finishes.

import tkinter as tkimport threadingimport timedef func(thread_number=[0]):   # note: the mutable default arg creates a closure that keeps track of the thread number.    global thr    local_thread_number = thread_number[0]    thread_number[0] += 1    def close():        thr = None        top.destroy()    top = tk.Toplevel(root)    text_field = tk.Text(top)    close_btn = tk.Button(top, text="Close", state=tk.DISABLED, command=close)    text_field.grid(row=1, column=0)    close_btn.grid(row=2, column=0)    for i in range(1, 100):        result = i**2        if i % 10 == 0:            text_field.insert(tk.END, str(result)+"\n")        time.sleep(0.05)    print(f'thread {local_thread_number} done!')    close_btn.config(state=tk.NORMAL)def get_and_start_thread():    global thr    thr = threading.Thread(target=func)    thr.start()root = tk.Tk()thr = Nonebutton_calc = tk.Button(root,text="Calculate",command=get_and_start_thread)button_calc.pack(side=tk.TOP)root.mainloop()


You need to thread the function that does the calculation, which is func. Right now you are threading the creation of another Tk instance and some widgets.

It can be something like this:

import tkinter as tkimport threadingimport time as tdef func():    frame = tk.Frame(root)    frame.pack()    textField = tk.Text(frame)    bCloseDialog = tk.Button(frame, text="Close", state=tk.DISABLED, command=root.destroy)    textField.grid(row=1, column=0)    bCloseDialog.grid(row=2, column=0)    for i in range(1,100):        result = i**2        textField.insert(tk.END,str(result)+"\n")        t.sleep(0.1)root = tk.Tk()thr = threading.Thread(target=func)buttonCalc = tk.Button(root,text="Calculate",command=thr.start)buttonCalc.pack(side=tk.TOP)root.mainloop()