From dfe99a97333014cfb40bb88eb1428ac3cbc5eab6 Mon Sep 17 00:00:00 2001 From: "Bobby Abellana (aider)" Date: Tue, 11 Feb 2025 16:27:49 -0800 Subject: [PATCH] refactor: Improve tkinter file dialog thread safety --- src/streamlit_app.py | 74 +++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/streamlit_app.py b/src/streamlit_app.py index 7f12ce0..399d2c6 100644 --- a/src/streamlit_app.py +++ b/src/streamlit_app.py @@ -210,22 +210,31 @@ with col1: else: # Windows or Linux import tkinter as tk from tkinter import filedialog - root = tk.Tk() - root.withdraw() - root.wm_attributes('-topmost', 1) - root.after(10) # Add a small delay - # Create and run the main loop in a way that doesn't block - path_holder = [] - def select_dir(): + import threading + import queue + + # Create a queue to pass the selected path between threads + path_queue = queue.Queue() + + def create_file_dialog(): + root = tk.Tk() + root.withdraw() + root.wm_attributes('-topmost', 1) path = filedialog.askdirectory(title="Select Source Directory") - path_holder.append(path) - root.quit() - root.after(20, select_dir) - root.mainloop() - if path_holder and path_holder[0]: - st.session_state['source_dir_selected'] = path_holder[0] + path_queue.put(path) + root.destroy() + + # Create and start the dialog in a new thread + dialog_thread = threading.Thread(target=create_file_dialog) + dialog_thread.start() + dialog_thread.join() # Wait for the thread to complete + + # Get the selected path from the queue + selected_path = path_queue.get() + + if selected_path: + st.session_state['source_dir_selected'] = selected_path st.rerun() - root.destroy() except Exception as e: st.error(f"Error selecting directory: {str(e)}") @@ -267,22 +276,31 @@ with col1: else: # Windows or Linux import tkinter as tk from tkinter import filedialog - root = tk.Tk() - root.withdraw() - root.wm_attributes('-topmost', 1) - root.after(10) # Add a small delay - # Create and run the main loop in a way that doesn't block - path_holder = [] - def select_dir(): + import threading + import queue + + # Create a queue to pass the selected path between threads + path_queue = queue.Queue() + + def create_file_dialog(): + root = tk.Tk() + root.withdraw() + root.wm_attributes('-topmost', 1) path = filedialog.askdirectory(title="Select Destination Directory") - path_holder.append(path) - root.quit() - root.after(20, select_dir) - root.mainloop() - if path_holder and path_holder[0]: - st.session_state['dest_dir_selected'] = path_holder[0] + path_queue.put(path) + root.destroy() + + # Create and start the dialog in a new thread + dialog_thread = threading.Thread(target=create_file_dialog) + dialog_thread.start() + dialog_thread.join() # Wait for the thread to complete + + # Get the selected path from the queue + selected_path = path_queue.get() + + if selected_path: + st.session_state['dest_dir_selected'] = selected_path st.rerun() - root.destroy() except Exception as e: st.error(f"Error selecting directory: {str(e)}")