Python Tkinter文件浏览器退出自动打开所在目录问题求解
问题描述
基于Python+Tkinter开发的文件浏览器已实现打开文件、打开文件夹、删除文件/文件夹、列出指定目录内容的核心功能,常规操作运行无异常,但存在固定Bug:程序启动后无任何操作、或是直接关闭程序时,会自动弹出程序源码所在的保存目录。
原始问题代码
#1 import all the libraries import os import tkinter.filedialog as fd import tkinter.messagebox as mb from tkinter import * #2 Defining the functions ->>>> four Function def open_file(): #a function for opening file file = fd.askopenfilename(title='choose a file to open',filetypes=[('All files','*.*')]) os.startfile(file) def open_folder(): foldertodlt = fd.askdirectory(title='Select a folder to Open') os.startfile(foldertodlt) def delete_file(): filetodlt = fd.askopenfilename(title='Select a File to Delete! ',filetypes=[('All files','*.*')]) os.remove(filetodlt) mb.showinfo(title='Deleting File', message='File Deleted! ') def delete_folder(): fodlertodlt = fd.askdirectory(title='Select a Folder to Delete! ') os.rmdir(fodlertodlt) mb.showinfo(title='Deleting Folder ?', message='Folder Deleted') def list_directories(): folder = fd.askdirectory(title='Select a Directory to list it's files and folders ') files = os.listdir(folder) listfiles = Toplevel(windowframe) listfiles.title(f'Files and Folders in {folder}') listfiles.resizable(1,1) listbox = Listbox(listfiles, selectbackground='gray', font=('courier',20)) listbox.place(relx=0,rely=0,relheight=1,relwidth=1) i = 0 while i <len(files): listbox.insert(END,files[i]) i += 1 #3 creating the window .. we must creat an object from the tkinter class and use it windowframe = Tk() windowframe.title('File Browser') windowframe.geometry('300x300') windowframe.resizable(0,0) windowframe.config(background='orange') windowframe.iconbitmap('icon.ico') #4 creating the buttons to and calling the functions Button (windowframe, text='Open a File',foreground='white', width=20, font='Courier',background='gray',command=open_file).place(x=50,y=50) Button (windowframe, text='Open a Folder',foreground='white',width=20, font='Courier',background='gray',command=open_folder).place(x=50,y=100) Button (windowframe, text='Delete a File',foreground='white',width=20,font='Courier',background='gray',command=delete_file).place(x=50, y= 150) Button (windowframe, text='Delete a Folder',foreground='white',width=20,font='courier',background='gray',command=delete_folder).place(x=50, y=200) Button (windowframe, text='List all Directories',foreground='white',width=20,font='courier',background='gray',command=list_directories).place(x=50, y=250) windowframe.update() windowframe.mainloop()
故障原因
- 主窗口启动前多余调用
windowframe.update(),打乱Tkinter原生窗口初始化时序,导致文件选择对话框组件在初始化阶段被异常触发,返回空路径值。 - 所有文件/文件夹选择逻辑未做空路径校验:当用户点击对话框「取消」按钮、或是组件异常返回空字符串时,直接调用
os.startfile(""),Windows系统下该语句的默认行为就是打开程序当前工作目录(即源码保存目录)。 - 图标加载逻辑无异常捕获,若运行目录下不存在
icon.ico文件,会触发Tkinter内部组件状态异常,间接导致对话框误触发。 - 原始代码存在语法错误:
list_directories函数的对话框标题用单引号包裹时,it's中的单引号会提前截断字符串,直接触发运行报错。
修复方案
- 删除
windowframe.mainloop()前多余的windowframe.update()调用,遵循Tkinter标准事件循环初始化逻辑。 - 所有文件/文件夹选择对话框的返回值,先判断是否为空,为空则直接终止后续文件操作,避免空路径传入系统接口。
- 给图标加载增加异常捕获,避免图标文件缺失导致的程序异常。
- 给所有文件对话框、消息框指定
parent参数绑定主窗口,避免焦点错位导致的组件异常。 - 修正字符串引号嵌套的语法错误。
修复后可运行代码
import os import tkinter.filedialog as fd import tkinter.messagebox as mb from tkinter import * def open_file(): file = fd.askopenfilename( parent=windowframe, title='choose a file to open', filetypes=[('All files','*.*')] ) if not file: return os.startfile(file) def open_folder(): foldertodlt = fd.askdirectory( parent=windowframe, title='Select a folder to Open' ) if not foldertodlt: return os.startfile(foldertodlt) def delete_file(): filetodlt = fd.askopenfilename( parent=windowframe, title='Select a File to Delete! ', filetypes=[('All files','*.*')] ) if not filetodlt: return os.remove(filetodlt) mb.showinfo(title='Deleting File', message='File Deleted! ', parent=windowframe) def delete_folder(): fodlertodlt = fd.askdirectory( parent=windowframe, title='Select a Folder to Delete! ' ) if not fodlertodlt: return os.rmdir(fodlertodlt) mb.showinfo(title='Deleting Folder ?', message='Folder Deleted', parent=windowframe) def list_directories(): folder = fd.askdirectory( parent=windowframe, title="Select a Directory to list it's files and folders " ) if not folder: return files = os.listdir(folder) listfiles = Toplevel(windowframe) listfiles.title(f'Files and Folders in {folder}') listfiles.resizable(1,1) listbox = Listbox(listfiles, selectbackground='gray', font=('courier',20)) listbox.place(relx=0,rely=0,relheight=1,relwidth=1) for f in files: listbox.insert(END, f) windowframe = Tk() windowframe.title('File Browser') windowframe.geometry('300x300') windowframe.resizable(0,0) windowframe.config(background='orange') # 增加图标加载异常捕获 try: windowframe.iconbitmap('icon.ico') except: pass Button(windowframe, text='Open a File',foreground='white', width=20, font='Courier',background='gray',command=open_file).place(x=50,y=50) Button(windowframe, text='Open a Folder',foreground='white',width=20, font='Courier',background='gray',command=open_folder).place(x=50,y=100) Button(windowframe, text='Delete a File',foreground='white',width=20,font='Courier',background='gray',command=delete_file).place(x=50, y= 150) Button(windowframe, text='Delete a Folder',foreground='white',width=20,font='courier',background='gray',command=delete_folder).place(x=50, y=200) Button(windowframe, text='List all Directories',foreground='white',width=20,font='courier',background='gray',command=list_directories).place(x=50, y=250) windowframe.mainloop()
内容的提问来源于stack exchange,提问作者Wahid Anwari
相关产品推荐
相关产品推荐

