快速简单的 Python 文件对话框?

我有一个简单的脚本,它解析文件并将其内容加载到数据库。我不需要 UI,但是现在我提示用户使用 raw_input解析文件,这是最不友好的,特别是因为用户不能复制/粘贴路径。我想一个快速和简单的方式来提出一个文件选择对话框给用户,他们可以选择的文件,然后它的加载到数据库。(在我的用例中,如果他们碰巧选择了错误的文件,那么解析就会失败,而且即使将其加载到数据库中也不会有问题。)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

这段代码接近于我想要的,但是它留下了一个恼人的空框架(这个框架无法关闭,可能是因为我还没有注册一个关闭事件处理程序)。

我不必使用 tkInter,但是由于它位于 Python 标准库中,因此它是最快和最简单的解决方案的一个很好的候选者。

在没有任何其他 UI 的情况下,在脚本中提示输入文件或文件名有什么快速简单的方法吗?

358386 次浏览

如果不需要用户界面或者希望程序在 CLI 中运行,可以将文件路径作为参数进行解析。这将允许您使用 CLI 的自动完成特性来快速查找所需的文件。

只有当脚本除了文件路径输入之外是非交互的时候,这才可能方便。

你可以使用 容易归:

import easygui


path = easygui.fileopenbox()

要安装 easygui,可以使用 pip:

pip3 install easygui

它是一个使用 tkinter的纯 Python 模块(easygui.py)。

试试 WxPython:

import wx


def get_path(wildcard):
app = wx.App(None)
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
dialog = wx.FileDialog(None, 'Open', wildcard=wildcard, style=style)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
else:
path = None
dialog.Destroy()
return path


print get_path('*.txt')

如果您不想有任何其他依赖项,Tkinter 是最简单的方法。 为了只显示对话框而不显示任何其他 GUI 元素,您必须使用 withdraw方法隐藏根窗口:

import tkinter as tk
from tkinter import filedialog


root = tk.Tk()
root.withdraw()


file_path = filedialog.askopenfilename()

Python 2变体:

import Tkinter, tkFileDialog


root = Tkinter.Tk()
root.withdraw()


file_path = tkFileDialog.askopenfilename()

pywin32提供对 GetOpenFileName win32函数的访问

import win32gui, win32con, os


filter='Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0'
customfilter='Other file types\0*.*\0'
fname, customfilter, flags=win32gui.GetOpenFileNameW(
InitialDir=os.environ['temp'],
Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
File='somefilename', DefExt='py',
Title='GetOpenFileNameW',
Filter=filter,
CustomFilter=customfilter,
FilterIndex=0)


print 'open file names:', repr(fname)
print 'filter used:', repr(customfilter)
print 'Flags:', flags
for k,v in win32con.__dict__.items():
if k.startswith('OFN_') and flags & v:
print '\t'+k

使用 Tkinter (python2)或 Tkinter (python3)确实可以显示文件打开对话框(请参阅其他答案)。但是请注意,该对话框的用户界面已经过时,并且与 Windows10中可用的较新的文件打开对话框不相对应。

此外,如果您正在寻找将 python 支持嵌入到您自己的应用程序中的方法,那么您很快就会发现 tkinter 库不是开源代码,而是商业库。

(例如,搜索“ activetcl 价格”将导致您到这个网页: https://reviews.financesonline.com/p/activetcl/)

因此,对于任何想要嵌入 python 的应用程序来说,tkinter 库都是要花钱的。

我自己设法找到了 pythonnet 图书馆:

(麻省理工学院执照)

使用以下命令可以安装 pythonnet:

pip3 install pythonnet

在这里你可以找到使用打开文件对话框的工作示例:

Https://stackoverflow.com/a/50446803/2338477

让我在这里也复制一个例子:

import sys
import ctypes
co_initialize = ctypes.windll.ole32.CoInitialize
#   Force STA mode
co_initialize(None)


import clr


clr.AddReference('System.Windows.Forms')


from System.Windows.Forms import OpenFileDialog


file_dialog = OpenFileDialog()
ret = file_dialog.ShowDialog()
if ret != 1:
print("Cancelled")
sys.exit()


print(file_dialog.FileName)

如果你还错过了更复杂的用户界面-见 演示文件夹 在蟒蛇的废物。

我不确定是否可以移植到其他操作系统上,还没有试过,但是。Net 5计划移植到多个操作系统(搜索“ .net 5平台”,https://devblogs.microsoft.com/dotnet/introducing-net-5/)-所以这项技术也是未来的证明。

另一个 OS 不可知的选项是使用 Pywebview:

import webview


def webview_file_dialog():
file = None
def open_file_dialog(w):
nonlocal file
try:
file = w.create_file_dialog(webview.OPEN_DIALOG)[0]
except TypeError:
pass  # user exited file dialog without picking
finally:
w.destroy()
window = webview.create_window("", hidden=True)
webview.start(open_file_dialog, window)
# file will either be a string or None
return file


print(webview_file_dialog())


环境: python3.8.6 on Mac-尽管我以前在 windows 10上使用过 pywebview。

我无意中发现了一个只适用于 Windows 的小技巧: 从 subprocess 运行 powershell.exe。

import subprocess


sys_const = ssfDESKTOP # Starts at the top level
# sys_const = 0x2a # Correct value for "Program Files (0x86)" folder
powershell_browse = "(new-object -COM 'Shell.Application')."
powershell_browse += "BrowseForFolder(0,'window title here',0,sys_const).self.path"


ret = subprocess.run(["powershell.exe",powershell_browse], stdout=subprocess.PIPE)
print(ret.stdout.decode())

注意系统文件夹常量的可选用法。(shldisp.h 中有一个模糊的输入错误,即“ Program Files (0x86)”常量的分配是错误的。我添加了一个具有正确值的注释。我花了一点时间才弄明白这一点。)

更多信息如下:

系统文件夹常数