Search code examples
pythonpython-multithreading

Python tkinter popup not opening prior to subthread


I am trying to open a popup that shows a progress bar here, and I'm running into a problem where the popup doesn't open until after the thread completes (the thread starts after the popup is called).

Additionally, I can get the popup to show before the thread starts by calling .pack() on self.bar because this errors out as below: (I get the same error if I call .pack separate from the .grid call)

File "\hinter\ui\progress.py", line 26, in __init__
    self.bar.grid(row=2, column=0).pack()
AttributeError: 'NoneType' object has no attribute 'pack'

This is the code where I line everything up:

progress_popup = hinter.ui.progress.Progress(0, 'Downloading and processing: Champions') # Should open popup
the_thread = threading.Thread(
    target=self.load_champions,
    args=(refresh,)
)
the_thread.start() # Run the download code in another thread
the_thread.join() # Wait to finish, so downloads can be completed one at a time for now
progress_popup.update(20, 'next') # Update the popup

This code is the bulk of Progress.__init__, where the popup should open:

self.popup = Toplevel()

Label(self.popup, text='Downloading Game data ...').grid(row=0, column=0, padx=20)
self.status_text = Label(self.popup, text=current_status)
self.status_text.grid(row=3, column=0, padx=20)

self.bar = Progressbar(self.popup, orient=HORIZONTAL, length=100, mode='determinate')
self.bar['value'] = self.current_percentage
self.bar.grid(row=2, column=0)

I am just not understanding why the popup like ... takes so long to open, or something, unless I cause it to error out in which case it opens instantly.


Solution

  • Try adding self.bar.update() to your Progress.__init__ method.

    progress_bar.update() updates the bar with the value set in progress_bar['value'], so maybe calling that after setting up the progress bar would make it display?

    Like so:

    self.popup = Toplevel()
    
    Label(self.popup, text='Downloading Game data ...').grid(row=0, column=0, padx=20)
    self.status_text = Label(self.popup, text=current_status)
    self.status_text.grid(row=3, column=0, padx=20)
    
    self.bar = Progressbar(self.popup, orient=HORIZONTAL, length=100, mode='determinate')
    self.bar['value'] = self.current_percentage
    self.bar.grid(row=2, column=0)
    self.bar.update()