[Python] Tkinter app freezes when using filedialog.askdirectory() in scrollable Canvas layout

Discussão em 'Python' iniciado por Stack, Julho 11, 2025.

  1. Stack

    Stack Membro Participativo

    I'm building a Python application using Tkinter.

    In the main window, I have a Canvas with a scrollable Frame inside it. Within that scrollable frame, I've added several LabelFrame widgets. Each LabelFrame contains a "Select Path" button, which is supposed to open a folder selection dialog.

    Here’s the simplified structure:

    Tk() window

    └── Canvas

    └── Scrollable Frame

    └── Multiple LabelFrames

    └── Each with a "Select Path" button

    Each button calls the following function:

    def select_path(self):
    filedialog.askdirectory()


    All button commands are correctly set (using command=self.select_path, not self.select_path()). However, every time I click a button, the application freezes and shows "(Not Responding)" in the title bar.

    If I use filedialog.askopenfile() instead of askdirectory(), everything works fine.

    I’ve also tried passing the parent argument and using tricks like self.lift() and -topmost, but the freeze still occurs.

    Any ideas why askdirectory() causes the app to freeze in this layout, while askopenfile() does not?

    Thank you!

    GUI

    After following furas's recommendation, I reduced my code to only use the canvas, frames, and path buttons, and everything works fine. However, my main application still doesn't work.

    This is my reduced code.

    import tkinter
    from tkinter import ttk, VERTICAL, ALL
    from tkinter import filedialog as fd


    class MyApp(tkinter.Tk):

    def __init__(self):
    super().__init__()

    self.path_button = None
    self.label_frame_3 = None
    self.label_frame_2 = None
    self.label_frame_1 = None


    self.title('My application')
    self.resizable(False, False)
    self.geometry('1200x500')
    self.current_window = None

    self.scrollable_frame = None
    self.y_scrollbar = None
    self.my_canvas = None

    self.create_gui()

    def create_gui(self):

    # scroll

    # create a container frame for scrolling
    self.my_canvas = tkinter.Canvas(self)
    # add a Scrollbars to Canvas
    self.y_scrollbar = ttk.Scrollbar(self.my_canvas, orient=VERTICAL, command=self.my_canvas.yview)
    # Configure the canvas
    self.my_canvas.configure(yscrollcommand=self.y_scrollbar.set, width=500, height=500)

    def on_mousewheel(event):
    self.my_canvas.yview_scroll(int(-1*(event.delta/60)), "units")

    # create another frame inside my_canvas
    self.scrollable_frame = tkinter.Frame(self.my_canvas, bg='white')

    self.my_canvas.bind("<Configure>", lambda e: self.my_canvas.configure(scrollregion=self.my_canvas.bbox(ALL)))
    self.my_canvas.bind_all("<MouseWheel>", on_mousewheel)

    self.my_canvas.create_window((0, 0), window=self.scrollable_frame, anchor='nw')

    # place scroll and scroll-bar
    self.my_canvas.pack(side='left', fill='both', expand=True)
    self.y_scrollbar.pack(side='right', fill='y')

    # end scroll

    self.create_all_labels(200, 200)

    def create_all_labels(self, width, height):

    # create and place frame 1
    self.label_frame_1 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 1 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_1.grid(column=0, row=1, padx=5, pady=5)
    self.create_frame(self.label_frame_1, "label_frame_1")

    # create and place frame 2
    self.label_frame_2 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 2 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_2.grid(column=1, row=1, padx=5, pady=5)
    self.create_frame(self.label_frame_2, "label_frame_2")

    # create and place frame 3
    self.label_frame_3 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 3 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_3.grid(column=2, row=1, padx=5, pady=5)
    self.create_frame(self.label_frame_3, "label_frame_3")

    # create and place frame 4
    self.label_frame_4 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 4 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_4.grid(column=0, row=2, padx=5, pady=5)
    self.create_frame(self.label_frame_4, "label_frame_4")

    # create and place frame 5
    self.label_frame_5 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 5 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_5.grid(column=1, row=2, padx=5, pady=5)
    self.create_frame(self.label_frame_5, "label_frame_5")

    # create and place frame 6
    self.label_frame_6 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 6 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_6.grid(column=2, row=2, padx=5, pady=5)
    self.create_frame(self.label_frame_6, "label_frame_6")


    # create and place frame 7
    self.label_frame_7 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 7 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_7.grid(column=0, row=3, padx=5, pady=5)
    self.create_frame(self.label_frame_7, "label_frame_7")

    # create and place frame 8
    self.label_frame_8 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 8 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_8.grid(column=1, row=3, padx=5, pady=5)
    self.create_frame(self.label_frame_8, "label_frame_8")

    # create and place frame 9
    self.label_frame_9 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 9 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_9.grid(column=2, row=3, padx=5, pady=5)
    self.create_frame(self.label_frame_9, "label_frame_9")

    # create and place frame 10
    self.label_frame_10 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 10 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_10.grid(column=0, row=4, padx=5, pady=5)
    self.create_frame(self.label_frame_10, "label_frame_10")

    # create and place frame 11
    self.label_frame_11 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 11 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_11.grid(column=1, row=4, padx=5, pady=5)
    self.create_frame(self.label_frame_11, "label_frame_11")

    # create and place frame 12
    self.label_frame_12 = tkinter.LabelFrame(self.scrollable_frame, text=" LabelFrame 12 ", labelanchor='nw', width=width,
    height=height)
    self.label_frame_12.grid(column=2, row=4, padx=5, pady=5)
    self.create_frame(self.label_frame_12, "label_frame_12")



    def create_frame(self, frame: tkinter.LabelFrame, name: str):

    # create and place Select Path button
    self.path_button = tkinter.Button(frame, text=" Select Path ", command=self.select_path)
    self.path_button.place(x=20, y=20)

    def select_path(self):
    print("before")
    destination = fd.askdirectory(initialdir="C:", title="Select")
    print("after")


    def main_loop(self):
    self.mainloop()


    myapp = MyApp()
    myapp.mainloop()

    Continue reading...

Compartilhe esta Página