2

In Tkinter, I have a window that I would like to create when a process is initialized to run another Python script, which would then close when the script completes. Below is what I have so far:

window = tk.Toplevel()
window.geometry("400x90")
window.wm_title("Process is Running")
process = subprocess.Popen("python3 run_a_script.py", shell=True)
process.wait()
window.destroy()

The script is running, but the popup window never appears. It does appear after the script completes if I remove window.destroy(), but it does not automatically close.

Is there a way to have the window be created before run_a_script.py is run, and then have it automatically close when the script completes?

WB_S2S
  • 87
  • 7
  • Is window.destroy() the last line in the script? As if so it meets your requirements; the window is closed at the end of the script. – PotSkill Oct 07 '21 at 23:07
  • This code is actually a function triggered by pushing a button, but yes, that's the end of the function. However, the button indents (as though it's been pressed) and remains indented while run_a_script.py runs. When run_a_script.py completes, no popup window appears. So, I believe it is creating and then destroying the window after the script is run. – WB_S2S Oct 07 '21 at 23:13
  • Can you please provide run_a_script.py - it might be just running the script and then it runs it is so fast that it already closes just moments after it is created. – PotSkill Oct 07 '21 at 23:27

2 Answers2

2

If I'm interpreting this right, then you never tell the window to "appear". Try adding:

window.update_idletasks()
window.update()

or

window.mainloop()

to show the window

Edit: Also, I typically use tk.Tk() for the main window instead of tk.Toplevel() for clarity. What's the difference between tkinter's Tk and Toplevel classes?

Mandias
  • 742
  • 5
  • 17
  • Ah, I should've included the main window, using tk.Tk(). This is a popup that appears after a button is pressed in the main window. – WB_S2S Oct 08 '21 at 20:25
2

All tkinter updates are handled by the tkinter mainloop and during the execution of the external script, tkinter mainloop does not take the control until after window.destroy(), so you cannot see the window because it has been destroyed when tkinter takes back the control.

To show the window during the execution of the external script, you can:

  • call window.update_idletasks() before calling subprocess.Popen(...) to let tkinter to show the window. However you cannot interact with the GUI during the execution of the external script.
window = tk.Toplevel()
window.geometry("400x90")
window.wm_title("Process is Running")
window.update_idletasks() # show the window
process = subprocess.Popen(["python3", "run_a_script.py"])
process.wait()
window.destroy()
  • use .after() to check periodically whether the process has completed or not.
window = tk.Toplevel()
window.geometry("400x90")
window.wm_title("Process is Running")
process = subprocess.Popen(["python3", "run_a_script.py"])

def check_process():
    if process.poll() is None:
        # process is still running, check again 100ms later
        window.after(100, check_process)
    else:
        # prcoess is completed, destroy the window
        window.destroy()
check_process() # start the checking
acw1668
  • 40,144
  • 5
  • 22
  • 34