在Python中快速便捷的文件对话框?

问题:在Python中快速便捷的文件对话框?

我有一个简单的脚本,可以解析文件并将其内容加载到数据库中。我不需要用户界面,但是现在我提示用户使用raw_input最不友好的文件进行解析,尤其是因为用户无法复制/粘贴路径。我想要一种快速简便的方法来向用户显示文件选择对话框,他们可以选择文件,然后将其加载到数据库中。(在我的用例中,如果他们碰巧选择了错误的文件,它将无法解析,即使将其加载到数据库中也不会有问题。)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

这段代码接近我想要的代码,但是却留下了一个烦人的空框架(无法关闭,可能是因为我尚未注册close事件处理程序)。

我不必使用tkInter,但是因为它在Python标准库中,所以它是最快,最简单解决方案的理想选择。

在没有任何其他UI的情况下,在脚本中提示文件或文件名的快捷简便方法是什么?

I have a simple script which parses a file and loads it’s contents to a database. I don’t need a UI, but right now I’m prompting the user for the file to parse using raw_input which is most unfriendly, especially because the user can’t copy/paste the path. I would like a quick and easy way to present a file selection dialog to the user, they can select the file, and then it’s loaded to the database. (In my use case, if they happened to chose the wrong file, it would fail parsing, and wouldn’t be a problem even if it was loaded to the database.)

import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()

This code is close to what I want, but it leaves an annoying empty frame open (which isn’t able to be closed, probably because I haven’t registered a close event handler).

I don’t have to use tkInter, but since it’s in the Python standard library it’s a good candidate for quickest and easiest solution.

Whats a quick and easy way to prompt for a file or filename in a script without any other UI?


回答 0

如果您不希望有任何其他依赖项,则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()

Tkinter is the easiest way if you don’t want to have any other dependencies. To show only the dialog without any other GUI elements, you have to hide the root window using the withdraw method:

import tkinter as tk
from tkinter import filedialog

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

file_path = filedialog.askopenfilename()

Python 2 variant:

import Tkinter, tkFileDialog

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

file_path = tkFileDialog.askopenfilename()

回答 1

您可以使用easygui

import easygui

path = easygui.fileopenbox()

要安装easygui,您可以使用pip

pip3 install easygui

它是一个单纯Python模块(easygui.py),其用途tkinter

You can use easygui:

import easygui

path = easygui.fileopenbox()

To install easygui, you can use pip:

pip3 install easygui

It is a single pure Python module (easygui.py) that uses tkinter.


回答 2

尝试使用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')

Try with 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')

回答 3

如果不需要UI或希望程序在CLI中运行,则可以将文件路径解析为参数。这将使您可以使用CLI的自动完成功能来快速查找所需的文件。

如果脚本除了文件路径输入之外是非交互式的,这可能仅是方便的。

If you don’t need the UI or expect the program to run in a CLI, you could parse the filepath as an argument. This would allow you to use the autocomplete feature of your CLI to quickly find the file you need.

This would probably only be handy if the script is non-interactive besides the filepath input.


回答 4

退房EasyGUI,一个非常容易使用的模块,它应该做的工作- http://easygui.sourceforge.net/

你会使用这个API文档页面上详细介绍了fileopenbox功能- https://easygui.readthedocs.io/en/latest/api.html

Check out EasyGUI, a very easy to use module that should do the job – http://easygui.sourceforge.net/

You would use the fileopenbox function detailed on this api documentation page – https://easygui.readthedocs.io/en/latest/api.html


回答 5

pywin32提供对GetOpenFileNamewin32函数的访问。从例子

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

pywin32 provides access to the GetOpenFileName win32 function. From the example

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

回答 6

使用tkinter(python 2)或Tkinter(python 3),确实可以显示文件打开对话框(请参见此处的其他答案)。但是请注意,该对话框的用户界面已过时,并且与Windows 10中可用的较新文件打开对话框不对应。

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

(例如,搜索“ activetcl定价”将带您到此网页:https ://reviews.financesonline.com/p/activetcl/ )

因此,tkinter库将为要嵌入python的任何应用程序花费资金。

我自己设法找到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)

如果您还错过了更复杂的用户界面,请参阅pythonnet git中的Demo文件夹。

我不确定是否可以移植到其他操作系统,但是没有尝试过,但是计划将.net 5移植到多个操作系统(搜索“ .net 5平台”,https://devblogs.microsoft.com/dotnet/introducing -net-5 /)-因此该技术也可以用于未来。

Using tkinter (python 2) or Tkinter (python 3) it’s indeed possible to display file open dialog (See other answers here). Please notice however that user interface of that dialog is outdated and does not corresponds to newer file open dialogs available in Windows 10.

Moreover – if you’re looking on way to embedd python support into your own application – you will find out soon that tkinter library is not open source code and even more – it is commercial library.

(For example search for “activetcl pricing” will lead you to this web page: https://reviews.financesonline.com/p/activetcl/)

So tkinter library will cost money for any application wanting to embedd python.

I by myself managed to find pythonnet library:

(MIT License)

Using following command it’s possible to install pythonnet:

pip3 install pythonnet

And here you can find out working example for using open file dialog:

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

Let me copy an example also here:

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)

If you also miss more complex user interface – see Demo folder in pythonnet git.

I’m not sure about portability to other OS’s, haven’t tried, but .net 5 is planned to be ported to multiple OS’s (Search “.net 5 platforms”, https://devblogs.microsoft.com/dotnet/introducing-net-5/ ) – so this technology is also future proof.