简体   繁体   中英

Tkinter Toplevel widgets not displaying - python

I am working with a Toplevel window in python Tkinter and I cannot seem to get the embedded widgets to show up until my other code has completed. The frame shows up, it loops through my other code properly, but the text/progressbar widget only show up if I somehow interrupt the loop. The frame is successfully destroyed at the end. See below.

Here is my Toplevel code:

class ProgressTrack:
    def __init__(self, master, variable, steps, application):
        self.progress_frame = Toplevel(master)
        self.progress_frame.geometry("500x140+30+30")
        self.progress_frame.wm_title("Please wait...")
        self.progress_frame.wm_iconbitmap(bitmap="R:\\CHPcomm\\SLS\\PSSR\\bin\\installation_files\\icon\\PSIDiaryLite.ico")

        progress_text = Canvas(self.progress_frame)
        progress_text.place(x=20,y=20,width=480,height=60)
        progress_text.create_text(10, 30, anchor=W, width=460, font=("Arial", 12), text="Please do not use " + application + " during execution. Doing so, will interrupt execution.")

        self.progress_bar = Progressbar(self.progress_frame, orient='horizontal', length=440, maximum=steps, variable=variable, mode='determinate')
        self.progress_bar.place(x=20,y=100,width=450,height=20)

And I call it from an instance of the following class which is created when the user clicks a button on the master window:

class Checklist:
    def __init__(self, master, var):
        self.progress = ProgressTrack(master, 0, 5, 'Microsoft Word')

        while var:
            #MY OTHER CODE
            self.progress.progress_bar.step()
        self.progress.progress_frame.destroy()

You have to know that tkinter is single threaded. Also the window (and all you see on the screen) updates its appearance only when idle (doing nothing) or when you call w.update_idletasks() where w is any widget. This means when you are in a loop, changing a progress bar, nothing will happen on the screen until the loop is finished.

So your new code could now be

    while var:
        #MY OTHER CODE
        self.progress.progress_bar.step()
        self.progress.progress_frame.update_idletasks()
    self.progress.progress_frame.destroy()

Based upon the @Eric Levieil's link above, it was as simple as adding this to my code:

self.progress.progress_frame.update()

Full change:

class Checklist:
    def __init__(self, master, var):
        self.progress = ProgressTrack(master, 0, 5, 'Microsoft Word')

        while var:
            #MY OTHER CODE
            self.progress.progress_bar.step()
            self.progress.progress_frame.update()
        self.progress.progress_frame.destroy()

Thank you Eric!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM