macOS tkinter:askopenfilename的filetypes是如何工作的?

8

我的问题

  1. 由于它们处于灰色模式,因此无法在“过滤器”中切换文件类型(请参见下面的图片),如果按照下面我的代码设置了“文件类型”:
filetypes = [ 
            ("Python File", "*.py"), 
            ("Image File", "*.bmp"),
            ("All Files", "*.*")
            ]

尽管默认的文件类型是.py,但由于窗口中高亮显示了test.bmp,我们也可以选择.bmp。这意味着filetypes,即.py.bmp,可以同时被激活。这种Filter行为正常吗?
我期望的是,我可以从filetypes集合中单独选择一种类型,并且这些选项应该是互斥的(即如果在Filter中选择Python File (.py),那么只有.py文件可供在窗口中选择)。参见图像: Screenshot of dialog
以下是我的代码:
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import askopenfilename
# from tkinter.filedialog import askopenfile
# from tkinter.filedialog import askopenfilenames

filetypes = [ 
            ("Python File", "*.py"), 
            ("Image File", "*.bmp"),
            ("All Files", "*.*")
            ]

def OpenFile():
    p = askopenfilename(initialdir="../",
                           filetypes =filetypes,
                           title = "Choose a file.")
    print ("Path to File: \n", p)
    #Using try in case user types in unknown file 
    # or closes without choosing a file.
    # try:
    #     with open(p, 'r') as f:
    #         print("Content of File:\n", f.read())
    # except:
    #     print("Error!")

root = Tk()
root.title( "File Opener")
label = ttk.Label(root, 
                    text ="File Read Test!", 
                    foreground="red", 
                    font=("Helvetica", 16))
label.pack()

menu = Menu(root)
root.geometry("300x200")
root.config(menu=menu)

file = Menu(menu)
file.add_command(label = 'Open', command = OpenFile)
file.add_command(label = 'Exit', command = root.quit)
menu.add_cascade(label = 'File', menu = file)

root.mainloop()

更多示例:

  • 如果在下面的代码中删除("All Files", "*.*"),会发生什么?仍然无法在文件类型之间切换,.py.bmp都是活动的。所有其他文件类型与以前的设置一样不在范围内。
filetypes = [ 
            ("Python File", "*.py"), 
            ("Image File", "*.bmp")]

Screenshot of dialog

  • 如果我只留下 ("所有文件", "*.*"),那么结果就是我期望的,*.* 最终会影响对话框。
filetypes = [("All Files", "*.*")]

Screenshot of dialog

系统版本信息:

  • macOS Catalina
  • Python 3.7.5
  • Tkinter 8.6

1
我在macOS Catalina 10.15.5上遇到了完全相同的问题,使用从python.org下载的python 3.7.6版本,Tk / Tcl版本为8.6.8(内置)。相同的代码可在linux Ubuntu 20.24上正确运行。我认为您的代码是正确的。如果您找到解决方案,请告诉我。 - Santi Santichaivekin
@Space 你认为这个问题与Python版本有关吗?我已经检查了3.8.0(使用Pyenv安装)并且它没有起作用。 - Kuo
@stovfl 尝试了不同的通配符模式,如 *.* 或 *, *.py 或 .py...,但在这种情况下没有效果。我相信这个问题与如何指定文件模式无关。 - Kuo
@SantiSantichaivekin 在 Windows Subsystem Unbuntu 18.04 上运行也是可以的。 - Kuo
@Kuo 它也可以在Windows上安装的Python中运行,而无需Linux子系统。 - Santi Santichaivekin
显示剩余6条评论
2个回答

0

嗯,当我在我的Python Shell中运行您的代码时,它完美地工作。我真的无法解决您的Filter错误,但我已经修改了您的文件,以便您可以轻松访问这些文件类型。我插入了一个input()代码,以便您可以选择要访问的文件类型。

from tkinter import ttk
from tkinter.filedialog import askopenfilename

# from tkinter.filedialog import askopenfile
# from tkinter.filedialog import askopenfilenames

filetypes = input("Enter Filetype: ")
while True:
    if "All Files" in filetypes:
        ft = [("All Files", "*.*")]
        break
    elif "Python" in filetypes:
        ft = [("Python Files", "*.py")]
        break
    elif "Image" in filetypes:
        ft = [("Image Files", "*.bmp")]
        break
    else:
        continue


def OpenFile():

    p = askopenfilename(initialdir="../",
                        filetypes=ft,
                        title="Choose a file.")
    print("Path to File: \n", p)
    # Using try in case user types in unknown file
    # or closes without choosing a file.
    # try:
    #     with open(p, 'r') as f:
    #         print("Content of File:\n", f.read())
    # except:
    #     print("Error!")


root = Tk()
root.title("File Opener")
label = ttk.Label(root,
                  text="File Read Test!",
                  foreground="red",
                  font=("Helvetica", 16))
label.pack()

menu = Menu(root)
root.geometry("300x200")
root.config(menu=menu)

file = Menu(menu)
file.add_command(label='Open', command=OpenFile)
file.add_command(label='Exit', command=root.quit)
menu.add_cascade(label='File', menu=file)

root.mainloop()

-2
在我的系统上:
  • macOS Mojave 10.4.6
  • Python 3.8.0
  • TkVersion 8.6

我发现这个简单的解决方法可以让我得到期望的行为:

filetypes = [ 
            ("All Files", "*.*"),
            ("Python File", "*.py"), 
            ("Image File", "*.bmp"),
            ]

那就是,通过让它最初出现为"所有文件",然后在打开对话框中切换到其他类型,可以适当地过滤文件。

1
谢谢您的回答。但是我使用 Python 3.8.0 和不同的文件类型组合重新运行了此代码,过滤器问题仍然存在。我使用 Pyenv 创建虚拟环境和 macOS Catalina 10.15.1。我还通过 Conda 虚拟环境检查了 Python 3.6.9、3.7.3。所有版本都无法通过 选项-->过滤器 来选择文件类型。 - Kuo

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