使用简单对话框在Python中选择文件

184

我想在我的Python控制台应用程序中获取文件路径作为输入。

目前,我只能要求在控制台中输入完整路径。

是否有一种方法可以触发一个简单的用户界面,使用户可以选择文件而不是手动输入完整路径?


4
好问题。我正在寻找这个。我点了赞。谢谢! - Priya
11个回答

283
使用tkinter如何?
from Tkinter import Tk     # from tkinter import Tk for Python 3.x
from tkinter.filedialog import askopenfilename

Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file
print(filename)

完成!


我在Tk().withdraw()上遇到了TypeError: 'module' object is not callable错误 - 有什么想法吗? - user391339
2
我必须执行 root = Tk.Tk() 然后 root.withdraw()。现在打开的文件对话框窗口却无法关闭。 - user391339
45
使用Python 3.x,我相信“Tkinter”实际上应该全部小写,即“tkinter”。 - WestAce
2
@WestAce 是的,Python3中的“Tkinter”已更改为“tkinter”。 - Ben
7
有没有办法只允许特定类型的文件?例如,我希望用户只能选择图像文件。 - Shantanu Shinde
显示剩余3条评论

107

为了完整起见,以下是 Etaoin 的回答的 Python 3.x 版本:

from tkinter.filedialog import askopenfilename
filename = askopenfilename()

12
为了完全并行,可能还需要添加 import tkintertkinter.Tk().withdraw() - geometrian
5
这对我不起作用(在Mac上,Python 3.6.6)。GUI窗口会打开,但您无法关闭它,同时还会出现色球等待光标图标。 - Ben Vincent
4
我也有同样的问题。文件对话框无法关闭。 - Cabara
2
这段代码与被接受的答案完全相同,但是它是不完整的。 - eric
这段代码会导致 Jupyter Notebook v6.1.5 在 Windows 10 上崩溃。 - Rich Lysakowski PhD
显示剩余2条评论

45

使用EasyGui

import easygui
print(easygui.fileopenbox())

安装:

pip install easygui

演示:

import easygui
easygui.egdemo()

4
目前为止,这是最好的解决方案。主要原因是easygui是一个pip包,易于安装。 - Yonatan Naor
4
在Mac OSX 10.14.5、python 3.6.7和easygui 0.98.1环境下尝试此操作会导致严重崩溃,不建议使用。 - Christopher Barber
2
@Bricktop https://dev59.com/iHRA5IYBdhLWcg3wyRF6 ? - jfs
1
@ChristopherBarber,10.14.6也是一样的情况。Python总是自动退出。 - gaya
这似乎是针对Python 2的,因为easygui尝试导入Tkinter而不是tkinter。 - Craig
显示剩余2条评论

13

在Python 2中,使用tkFileDialog模块。

import tkFileDialog

tkFileDialog.askopenfilename()

在Python 3中,请使用tkinter.filedialog模块。

import tkinter.filedialog

tkinter.filedialog.askopenfilename()

1
它不是Python 3标准安装的一部分。 - miguelmorin

8

那么,如果文件是来自Excel,我该如何将文件路径放入pandas数据框中呢?pd.read_excel(r'file_path')无法工作。@SainathReddy - HelpMeCode
如果你打印出 file_path,你会发现它包含正斜杠而不是反斜杠。因此,pandas可以跨平台处理它(例如Windows和Linux)。只需要使用 pd.read_excel(file_path) 即可。 - Matthew Thomas

5

在这个后续的重复问题的答案中,如建议的那样,我使用了wxPython,结果比tkinter好得多:

https://dev59.com/oGox5IYBdhLWcg3wQSOp#9319832

与tkinter不同,wxPython版本产生的文件对话框看起来与我安装有xfce桌面的OpenSUSE Tumbleweed上几乎任何其他应用程序的打开文件对话框相同,而且布局宽敞、易读,不需要横向滚动。


5

另一个值得考虑的选择是Zenity:http://freecode.com/projects/zenity

我遇到这样一种情况,在开发Python服务器应用程序(没有GUI组件)时,因此不想引入任何python GUI工具包的依赖项,但我希望我的调试脚本能够通过输入文件进行参数化,并且如果用户在命令行上没有指定文件,则需要对用户发出视觉提示。 Zenity非常适合。要实现这一点,请使用subprocess模块调用“zenity --file-selection”并捕获stdout。当然,这种解决方案并不特定于Python。

Zenity支持多个平台,并且已经安装在我们的开发服务器上,因此它可以在不引入不必要的依赖项的情况下促进我们的调试/开发。


4

建议使用root.withdraw()这里也有)来隐藏窗口而不是删除它,在使用VS Code的交互式控制台时可能会出现问题("重复执行"错误)。

以下是两个片段,用于返回“打开”或“另存为”中选择的文件路径(在Windows上使用Python 3):

import tkinter as tk
from tkinter import filedialog

filetypes = (
    ('Text files', '*.TXT'),
    ('All files', '*.*'),
)

# open-file dialog
root = tk.Tk()
filename = tk.filedialog.askopenfilename(
    title='Select a file...',
    filetypes=filetypes,
)
root.destroy()
print(filename)

# save-as dialog
root = tk.Tk()
filename = tk.filedialog.asksaveasfilename(
    title='Save as...',
    filetypes=filetypes,
    defaultextension='.txt'
)
root.destroy()
print(filename)
# filename == 'path/to/myfilename.txt' if you type 'myfilename'
# filename == 'path/to/myfilename.abc' if you type 'myfilename.abc'

3
使用 Plyer,您可以在Windows、macOS、Linux甚至Android上获得本地文件选择器。
import plyer

plyer.filechooser.open_file()

有另外两种方法,choose_dirsave_file。详见文档此处

3
这会引发一个NotImplemented错误! - Dr. Hillier Dániel

2

这里有一个简单的函数,可以在终端窗口中显示文件选择器。此方法支持选择多个文件或目录。这样做的好处是即使在不支持GUI的环境下也能运行。

from os.path import join,isdir
from pathlib import Path
from enquiries import choose,confirm

def dir_chooser(c_dir=getcwd(),selected_dirs=None,multiple=True) :
    '''
        This function shows a file chooser to select single or
        multiple directories.
    '''
    selected_dirs = selected_dirs if selected_dirs else set([])

    dirs = { item for item in listdir(c_dir) if isdir(join(c_dir, item)) }
    dirs = { item for item in dirs if join(c_dir,item) not in selected_dirs and item[0] != "." } # Remove item[0] != "." if you want to show hidde

    options = [ "Select This directory" ]
    options.extend(dirs)
    options.append("⬅")

    info = f"You have selected : \n {','.join(selected_dirs)} \n" if len(selected_dirs) > 0 else "\n"
    choise = choose(f"{info}You are in {c_dir}", options)

    if choise == options[0] :
        selected_dirs.add(c_dir)

        if multiple and confirm("Do you want to select more folders?") :
            return get_folders(Path(c_dir).parent,selected_dirs,multiple)

        return selected_dirs

    if choise == options[-1] :
        return get_folders(Path(c_dir).parent,selected_dirs,multiple)

    return get_folders(join(c_dir,choise),selected_dirs,multiple)

To install enquiers do,

pip install enquiries


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接