Python 2.7 如何实现类原生系统的美观 Tkinter 文件浏览对话框
版本关联问题说明
你听到的说法属实。Python 2.7 内置的 Tkinter 版本过旧,其 tkFileDialog.askdirectory 组件调用的是 Windows 早期通用控件接口,未适配新版系统的原生对话框调用规范,因此只会渲染你看到的老旧样式:
而 Python 3.x 对 Tkinter 的文件对话框模块做了适配更新,默认会调用 Windows 最新的原生通用控件接口,直接就能实现你预期的效果:
可实现预期效果的替代方案
- 方案1:升级到 Python 3.x 版本
这是成本最低的方案,升级后直接导入tkinter.filedialog模块,调用askdirectory()方法即可,默认弹出的就是原生样式的文件夹选择对话框,无需额外配置。 - 方案2:Python 2.7 环境下通过 ctypes 调用系统原生 API
如果必须保留 Python 2.7 开发环境,可以直接调用 Windows 的 Shell32 接口实现原生对话框,参考代码如下:
import ctypes from ctypes import wintypes # 对话框配置常量 BIF_RETURNONLYFSDIRS = 1 BIF_NEWDIALOGSTYLE = 0x0040 def get_native_folder_path(title="选择文件夹"): shell32 = ctypes.windll.shell32 ole32 = ctypes.windll.ole32 # 初始化COM环境 ole32.CoInitialize(None) # 定义BROWSEINFO结构体 class BROWSEINFO(ctypes.Structure): _fields_ = [ ("hwndOwner", wintypes.HWND), ("pidlRoot", wintypes.LPCVOID), ("pszDisplayName", wintypes.LPWSTR), ("lpszTitle", wintypes.LPCWSTR), ("ulFlags", wintypes.UINT), ("lpfn", wintypes.LPARAM), ("lParam", wintypes.LPARAM), ("iImage", ctypes.c_int) ] browse_info = BROWSEINFO() browse_info.lpszTitle = title browse_info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE pidl = shell32.SHBrowseForFolderW(ctypes.byref(browse_info)) if pidl: selected_path = ctypes.create_unicode_buffer(wintypes.MAX_PATH) shell32.SHGetPathFromIDListW(pidl, selected_path) ole32.CoTaskMemFree(pidl) return selected_path.value return None
调用该函数即可弹出完全原生的文件夹选择对话框,返回值为用户选中的文件夹绝对路径。
- 方案3:使用pywin32模块的封装接口
若你的Python 2.7环境已安装pywin32,可以直接调用其封装好的Shell相关接口,代码更简洁,同样能唤起原生对话框。
内容的提问来源于stack exchange,提问作者Royi Levy
相关产品推荐
相关产品推荐

