Reputation: 13
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
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