0

I'm realtively new to python and am making a GUI app that does a lot of file i/o and processing. To complete this i would like to get a confirmation box to pop-up when the user commits and actions. From this when clicking 'yes' the app then runs the i/o and displays a progress bar.

From other threads on here I have gotten as far as reading about the requirement to create an addtional thread to take on one of these processes (for example Tkinter: ProgressBar with indeterminate duration and Python Tkinter indeterminate progress bar not running have been very helpful).

However, I'm getting a little lost because I'm not activating the threaded process from the Main() function. So I'm still getting lost in how, and where, I should be creating the progress bar and passing of the i/o process to another thread (reading in a csv file here).

Here is my code and I would be very grateful for any help anyone can give me:

import tkinter as tk
import tkinter.messagebox as messagebox
import csv
import tkinter.ttk as ttk
import threading

class ReadIn(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("Read in file and display progress")
        self.pack(fill=tk.BOTH, expand=True)

        self.TestBtn = tk.Button(self.parent, text="Do Something", command=lambda: self.confirm_pb())
        self.TestBtn.pack()

    def confirm_pb(self):
        result = messagebox.askyesno("Confirm Action", "Are you sure you want to?")
        if result:
            self.handle_stuff()

    def handle_stuff(self):
        nf = threading.Thread(target=self.import_csv)
        nf.start()
        self.Pbar()
        nf.join()

    def Pbar(self):
        self.popup = tk.Tk()
        self.popup.title('Loading file')
        self.label = tk.Label(self.popup, text="Please wait until the file is created")
        self.progressbar = ttk.Progressbar(self.popup, orient=tk.HORIZONTAL, length=200,
                                           mode='indeterminate')
        self.progressbar.pack(padx=10, pady=10)
        self.label.pack()
        self.progressbar.start(50)


    def import_csv(self):
        print("Opening File")
        with open('csv.csv', newline='') as inp_csv:
            reader = csv.reader(inp_csv)
            for i, row in enumerate(reader):
                # write something to check it reading
                print("Reading Row " + str(i))

def main():
    root = tk.Tk()  # create a Tk root window
    App = ReadIn(root)
    root.geometry('400x300+760+450')
    App.mainloop()  # starts the mainloop

if __name__ == '__main__':
    main()
Community
  • 1
  • 1
max00d
  • 78
  • 1
  • 4

1 Answers1

0

The statement nf.join() in function handle_stuff() will block tkinter's main loop to show the progress bar window. Try modify handle_stuff() as below:

def handle_stuff(self):
    nf = threading.Thread(target=self.import_csv)
    nf.start()
    self.Pbar()
    #nf.join() # don't call join() as it will block tkinter's mainloop()
    while nf.is_alive():
        self.update() # update the progress bar window
    self.popup.destroy()
acw1668
  • 40,144
  • 5
  • 22
  • 34