Search code examples
pythonuser-interfacetkinterpython-multithreading

Tkinter background progressbar function while another function runs


I made a GUI Python program with Tkinter. I made a progressbar using "from tkinter.ttk import Progressbar". When I press a button, I apply a function that do something and return a Boolean value. I need that the progressbar will run until that function ends the process, and after that it will stop.

from tkinter.ttk import Progressbar
import time
import threading

wheel_flag = False
root = tk.Tk()
wheel = Progressbar(row,orient=HORIZONTAL,length=100,mode="indeterminate")


def btn_function()
  loading_function = threading.Thread(target=start_loading)
  loading_function.start()
  boolean_wheel = threading.Thread(target=some_function, args = (x,y)) #"some_function" returns a boolean value
  boolean_wheel.start()
  while True:
    if not boolean_wheel.is_alive():
      break
  wheel_flag = True


def start_loading():
  while True:
    global wheel_flag
    wheel['value'] += 10
    root.update_idletasks()
    time.sleep(0.5)
        
    if wheel_flag:
        break


Here I don't get the boolean_wheel value, but I want to check if it true or false and send to the user message if function succeeded or not.

I want that when "btn_function" is applied, the progressbarwill start to load until "some_function" will finish run. Now the result I get is that the loading start only after "some_function" finished, and runs without stopping until I close the program.


Solution

  • the proper solution is to remove the loop in btn_function and instead have some_function set wheel_flag after it is done.

    def some_function_wrapper(*args,**kwargs):
        global wheel_flag
        some_function(*args,**kwargs)
        wheel_flag = True
    

    and call this instead of some_function inside your thread.

    now another solution is to just run the entire btn_function inside another thread, by adding

    command= lambda : threading.Thread(target=btn_function).start()
    

    inside your button definition, but nesting threads sometimes becomes hard to track.

    Edited: It works. I checked the function value inside that function

    def some_function_wrapper(*args,**kwargs):
        global wheel_flag
        check = some_function(*args,**kwargs)
        if check:
          print("works")
        else:
          print("don't work")
    
        wheel_flag = True