vincent9
vincent9

Reputation: 13

How to destroy tkinter mainloop when exception occurs in any module running in daemon thread

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()


Upvotes: 1

Views: 512

Answers (1)

Meritor
Meritor

Reputation: 166

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)

Upvotes: 0

Related Questions