-1

I need to display an indeterminate progress bar to indicate to the user that something is happening. I have found many examples but all are operated by a button and none shows how to display a progress bar while a function is performed. In addition, I want to display the progress bar when the function starts and disappear it at the end of the function, without the user having to press any button or close the window. My main problem is that I can only display the progress bar if I use the mainloop() function and in this case my program is blocked until I close the window. as advised, I tried to start the progress bar in a different thread, currently without success

This is my code :

main.py

import time
import ProgressBar

print("start")
print("sleep 5 seconds")
pb = ProgressBar.ProgBar()
time.sleep(5)
pb.stop()
print("end")

ProgressBar.py

from tkinter import *
from tkinter import ttk
from threading import thread

class ProgBar(Frame):
  def __init__(self):
    Frame.__init__(self)
    self.master.title("ProgressBar example")
    self.grid(sticky=E+W+N+S)
    self.pbar = ttk.Progressbar(self, orient="horizontal", length=300, mode="indeterminate", maximum=100)
    self.pbar.grid(row=0, column=0, pady=2, padx=2, sticky=E+W+N+S, columnspan=3)
    self.start()

  def start(self):
    def start_thread(self):
      self.pbar.start()
      self.mainloop()     
  Thread(target=start_thread, args=(self,)).start()

  def stop(self):
    self.pbar.stop()
    self.destroy()
BlackMat
  • 41
  • 2
  • 7

1 Answers1

0

You need to call the function in a different thread to the one that tkinter's mainloop is running in. You can do this using Python's threading import quite easily:

import threading
x = threading.Thread(target=thread_function, args=(1,))
x.start()

When you start your ProgBar, mainloop is gonna block before you can start the thread for execution of your function. To get round this, before you start your mainloop, call self.after(100, self.start_thread_function). This will queue your function to start the thread for your function to happen after 100ms. You can tune this time however you wish.

Finally, once your function is finished, you can simply call your stop function from the function itself. Usually, UI affecting calls made outside of the UI loop would cause you issues, but because of the way that threading works in Python, it's not something you have to worry about here.

Benjamin James Drury
  • 2,353
  • 1
  • 14
  • 27
  • i understand the logic you described but i didn't succeeded to wrote a correct code. I change the function `start()` in ProgressBar.py in the question. – BlackMat Mar 30 '20 at 09:20