我该如何在Tkinter中使用同一个对话框来浏览和选择文件和目录?

4
我将使用Tkinter为Python脚本构建GUI。我需要一个按钮,打开一个对话框,让我选择文件和文件夹。到目前为止,我遇到了:
tkFileDialog.askdirectory(parent=root, title=dirtext1)

这允许在对话框中仅选择目录,而不是文件。

tkFileDialog.askopenfilename(parent=root, title=filetext)

目前我需要通过单独的按钮访问这些对话框,每个按钮都调用其中一个功能,以便我能够选择文件。是否有一种方法可以使用单个对话框来选择文件或文件夹?


1
当按钮被按下时,您想依次调用askdirectory()askopenfilename()吗? - Stop harming Monica
不,我希望有一个共同的对话框,用于选择文件或文件夹。(编辑问题以澄清) - Dhruv Mullick
虽然 tkinter 没有内置的方法来实现这一点,但您可以使用 tkinter.askopenfilename() 要求用户选择一个文件,然后在所选文件上使用 os.path.dirname() 来获取所选文件所在的目录,从而有效地从同一对话框中返回文件和目录。 - R. Kap
我认为你不能这样做,每个任务都需要不同的行为。如果用户选择一个目录并按下“确定”或“打开”按钮或双击它,那么对话框应该显示目录的内容还是仅返回它? - Stop harming Monica
很抱歉,您需要自己实现该行为,并且没有太多可重用的组件可供使用。这个问题的答案可以给你一些提示:https://dev59.com/qm7Xa4cB1Zd3GeqPlQqr - Stop harming Monica
显示剩余3条评论
2个回答

9
我不这么想。没有内置的类可以轻松地完成它。
调查
如果您查看tkFileDialog模块的源代码,OpenDirectory类都继承自_Dialog,位于tkCommonDialog中。
到目前为止还不错;这些类很简单,只扩展了两种方法。_fixresult是一个根据您的选项进行过滤的钩子(很有前途),_fixoptions添加了正确的tcl参数(例如初始目录)。
但是当我们进入Dialog类(_Dialog的父类)时,我们会发现它通过给定的名称调用了一个tcl命令。内置的名称是“tk_getOpenFile”和“tk_chooseDirectory”。此后,我们在python级别上没有太多的命令自由度。如果我们去查看其他tcl脚本可用性,我们会感到失望
看起来你的选择是
  • ttk::getOpenFile:获取打开文件的路径。
  • ttk::getSaveFile:获取保存文件的路径。
  • ttk::chooseDirectory:选择目录。
  • ttk::getAppendFile:获取追加文件的路径。

结论

糟糕!不过,你可以使用列表框、输入框、按钮(和其他tk内置控件)以及os模块很容易地制作自己的对话框。

简单替代方案

根据您的评论,一个可行的简单解决方案可能是使用

directory = os.path.dirname(os.path.realpath(tkFileDialog.askopenfilename()))

他们需要选择一个文件,但“打开”按钮将“返回路径”,这意味着路径是从文件位置计算出来的。
但我真的想要它!
如果由于某种原因您确实想要此行为但不想重新制作小部件,则可以直接调用tcl脚本。可能可以从getOpenFile中复制代码并提供更松散的参数,以允许选择更通用的对象。这不是我的专长,似乎是一个非常糟糕的主意,但此处是如何直接调用tcl的方法,此处是您可以了解更多关于底层命令的信息的地方。

0
我曾经遇到过类似的问题。 最后,我使用了askopenfilenames()(复数形式),并从文件中分离出路径。然后用一个单选按钮让用户选择是要处理目录中的所有文件还是只选择他们想要处理的文件。
filetypes = [('All files', '*.*'), ('CSV files', '*.csv'),]
data_list = askopenfilenames(title='Select folder', filetypes=filetypes)
data_dir = data_list[0].rsplit('/', 1)[0]

我提到这个是因为askopenfilenames()并不常被建议使用,但它更接近于选择一个文件夹,因为可以使用ctrl+A选择所有文件。

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