Tkinter滚动Canvas布局中filedialog.askdirectory()触发程序冻结的问题求助
Tkinter滚动Canvas布局中filedialog.askdirectory()触发程序冻结的问题求助
我正在用Tkinter开发一个Python应用,主窗口里有个Canvas,里面嵌套了一个可滚动的Frame,这个滚动Frame里又放了好几个LabelFrame,每个LabelFrame里都有个“Select Path”按钮,本来应该弹出文件夹选择对话框的。
按钮绑定的函数如下:
def select_path(self): filedialog.askdirectory()
按钮的命令设置是对的(用的command=self.select_path,不是加括号的调用),但每次点击按钮,程序就会卡住,标题栏显示“(Not Responding)”。奇怪的是,如果换成filedialog.askopenfile()就完全正常。我试过给对话框传parent参数,也试过self.lift()、设置置顶窗口这些小技巧,但还是会冻结。
有没有人知道为什么在这个布局下askdirectory()会导致程序卡死,而askopenfile()却不会?谢谢!
补充说明
按照furas的建议,我把代码精简到只保留Canvas、Frame和路径按钮,这时候一切正常,但我的主程序还是有问题。以下是我精简后的测试代码:
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): # 滚动区域设置 # 创建Canvas容器 self.my_canvas = tkinter.Canvas(self) # 给Canvas添加垂直滚动条 self.y_scrollbar = ttk.Scrollbar(self.my_canvas, orient=VERTICAL, command=self.my_canvas.yview) # 配置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") # 在Canvas内部创建可滚动的Frame 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') # 放置Canvas和滚动条 self.my_canvas.pack(side='left', fill='both', expand=True) self.y_scrollbar.pack(side='right', fill='y') # 滚动区域设置结束 self.create_all_labels(200, 200) def create_all_labels(self, width, height): # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") # 创建并放置LabelFrame 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") def create_frame(self, parent, frame_name): # 补全按钮创建逻辑,原精简代码遗漏了这部分 self.path_button = ttk.Button(parent, text="Select Path", command=self.select_path) self.path_button.pack(pady=10) def select_path(self): # 问题出在这里的askdirectory fd.askdirectory() # 如果换成下面这行就正常 # fd.askopenfile() if __name__ == "__main__": app = MyApp() app.mainloop()
内容来源于stack exchange
相关产品推荐
相关产品推荐

