Andermutu
Andermutu

Reputation: 134

Update a progressbar in a thread

I have a Python code where I create a progressbar. The Tkinter environment is created in the Gui function with the progressbar and it is launched as a thread. Then in an other thread I calculate the value that the progressbar must have, but the problem is that I dont know how to update the Gui thread with the new value of the progressbar. Here is my code:

import tkinter as tk
from tkinter import ttk
import thread

def Gui(): 
   root = tk.Tk()
   root.geometry('450x450')
   root.title('Hanix Downloader')

   button1 = tk.Button(root, text='Salir', width=25,command=root.destroy)
   button1.pack()

   s = ttk.Style()
   s.theme_use('clam')
   s.configure("green.Horizontal.TProgressbar", foreground='green', background='green')

   mpb = ttk.Progressbar(root,style="green.Horizontal.TProgressbar",orient ="horizontal",length = 200, mode ="determinate")
   mpb.pack()
   mpb["maximum"] = 3620
   mpb["value"] = 1000

   root.mainloop()

def main():
while True:
    #Calculate the new value of the progress bar.
    mpb["value"] = 100 #Does not work
    root.update_idletasks()#Does not work
    #Do some other tasks.


if __name__ == '__main__':
thread.start_new_thread( Gui,() )
thread.start_new_thread( main,() )

The error I get is that mpb and root do no exist. Thanks in advance.

Upvotes: 0

Views: 2432

Answers (1)

furas
furas

Reputation: 142641

You should get error because mpb and root are local variables which exist only in Gui but not in main. You have to use global to inform both functions to use global variables - and then main will have access to mpb created in Gui

I also add time.sleep(1) before while True: because sometimes main may start faster then Gui and it may not find mpb (because Gui had no time to create progressbar)

import tkinter as tk
from tkinter import ttk
import _thread
import time

def Gui():
   global root, mpb

   root = tk.Tk()

   button1 = tk.Button(root, text='Exit', command=root.destroy)
   button1.pack()

   mpb = ttk.Progressbar(root, mode="determinate")
   mpb.pack()

   mpb["maximum"] = 3000
   mpb["value"] = 1000

   root.mainloop()


def main():
    global root, mpb

    time.sleep(1)

    while True:
        mpb["value"] += 100
        #root.update_idletasks() # works without it

        #Do some other tasks.
        time.sleep(0.2)


if __name__ == '__main__':
    _thread.start_new_thread(Gui, ())
    _thread.start_new_thread(main, ())

Tested on Python 3.6.2, Linux Mint 18.2


EDIT: more precisely: you need global only in Gui because it assigns values to variables
root = ..., mpb = ....

Upvotes: 1

Related Questions