Home > Back-end >  How to destroy tkinter mainloop when exception occurs in any module running in daemon thread
How to destroy tkinter mainloop when exception occurs in any module running in daemon thread

Time:01-25

I wrote a Python (3.7) application that uses tkinter as GUI and runs the main function in a daemon thread. Is there a way to destroy the tkinter mainloop when an exception occurs in that daemon thread?

The issue is that the program has multiple modules. Is there a way to kill the mainloop if that happens in any of them? Otherwise the user will be left with a frozen GUI.

Here is the piece of code starting the thread:


import logging
import threading
from tkinter import *
from tkinter import ttk


def main_thread():

    if check_input():  # user provided necessary input
        program_thread = threading.Thread(target=program_pipeline)  # runs main
        program_thread.daemon = True  # daemon thread can be killed anytime?
        program_thread.start()
        block_user_entries()
        clear_results()  # from a previous run

    else:
        logging.info("\n--------------- TRY AGAIN -------------------\n")
        ublock_user_entries()


The program_pipeline communicates with multiple modules and packages

The thread starts when user clicks a button


analyze_button = ttk.Button(frame, text="Analyze", state="normal", command=main_thread)
analyze_button.grid(column=2, row=0, pady=2, sticky=(W))

root.mainloop()


CodePudding user response:

If I am interpreting this correctly, you are looking for a way to interrupting main thread from a daemon.

Now, generally this is not a recommended option, you can do the same using low level _thread.interrupt_main().

If you provide more information a better solution can be thought of.

import _thread
import threading
import tkinter as tk


def program_pipeline():
    try:
        # DO STUFF
        # calling other modules that may raise exception/error
        raise ValueError("Error")
    except BaseException as be:
        print("Exception in daemon", be)
        _thread.interrupt_main()


def main_thread():

    program_thread = threading.Thread(target=program_pipeline)
    program_thread.daemon = True
    program_thread.start()


root = tk.Tk()
analyze_button = tk.Button(root, text="Analyze", state="normal", command=main_thread)
analyze_button.grid(column=2, row=0, pady=2, sticky=tk.W)

try:
    root.mainloop()
except KeyboardInterrupt as kie:
    print("exception in main", kie)
  •  Tags:  
  • Related