0

So I previously had the same problem but I somehow fixed it. Now that I have started using Tkinter to display my output(Previously I just used the terminal) I have run into it again. I tried replicating my solution but it wont work. one of my threads(th1) wont terminate.

def wait_th2():
    while(True):
        if(not th2.is_alive()):
            print("1")
            time.sleep(5)
            root.destroy()
            break
        else:
            pass
    return
def start_process():
    global th2
    global th1
    th1 = Thread(target= wait_th2)
    th2 = Thread(target=main1)
    th2.start()
    return 
def on_closing():
    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        qu_main.put('q') # this is to inform the th2 thread that the user wants to terminate the Script
        print("added q")
        th1.start()
if __name__ == '__main__':
    
    qu_main = qu()
    root = tk.Tk()
    root.title("Ping Script GUI")

    text_output = tk.Text(root, wrap=tk.WORD)
    text_output.pack(fill=tk.BOTH, expand=True)

    sys.stdout.write = redirect_print  # Redirect print statements to GUI

    start_process()

    root.protocol("WM_DELETE_WINDOW", on_closing)
    
    root.mainloop()

So I have a script that runs and gives me an output once the output is given it goes to sleep for a certain amount of time. I wanted the ability to terminate the script at any point of time so even if was sleeping. Where I ran into problem is when I try to terminate the script while It is still running. I want my Tkinter window to stay open till the script terminates and all the output is given so I started a new thread that checks if the previous thread is terminated or not and if not it keeps the Tkinter window open till the previous thread terminates.

If I use join all my windows freeze and the kernel crashes. If I use sys.exit() th1 thread still remains active. Now the reason I am not using ctrl+C is I want to convert this python code into an executable file and run it on my PC.


EDIT I now use Timer as a way to check if my thread as been terminate or not

def start_process():
    global th2,th1
    th1 = Timer(5, wait_th2)
    th2 = Thread(target=main1)
    th2.start()
    return 
def wait_th2():
    if(not th2.is_alive()):
        root.destroy()
        th1.cancel()
    else:
        th1 = Timer(5, wait_th2)
        th1.start()

But for some reason the kernel still crashes while trying to re-execute the code

Cannot execute code, session has been disposed. Please try restarting the Kernel. StdErr from Kernel Process Tcl_AsyncDelete: async handler deleted by the wrong thread

3
  • 1
    problem might relate to thread synchronization and handling the tkinter GUI.You can use the after() method to periodically check the status of thread and update gui as same .by using this you cannot need to use seperate th1 to check if th2 is terminated or not
    – Hasan Raza
    Commented Jul 18, 2023 at 6:20
  • 2
    Note that you cannot call root.destroy() from a secondary thread. All GUI activity must be done from the main thread. This is a concrete rule for all modern UI framrworks. Commented Jul 18, 2023 at 7:10
  • @TimRoberts Thanks didn't know this as its my first time working with tkinter or any UI framework in general
    – Sahil Jain
    Commented Jul 18, 2023 at 7:19

0