macOS tkinter:askopenfilename 的文件类型如何工作

Kuo*_*Kuo 8 python macos file-type tkinter python-3.x

我的问题

  1. 不能filetypesFilter(见下图)之间切换,因为它们处于灰色模式,如果设置filetypes如下
filetypes = [ 
            ("Python File", "*.py"), 
            ("Image File", "*.bmp"),
            ("All Files", "*.*")
            ]
Run Code Online (Sandbox Code Playgroud)
  1. 虽然默认文件类型是.py我们也可以.bmp在窗口中选择,因为test.bmp突出显示。这意味着filetypes.py.bmp可以同时激活。这种Filter行为正常吗?

我想到的是,我们可以从一组挑选出一个类型filetypes和这些选项应mutually exclusive,也就是说,如果选择Python File (.py)Filter,那么只有.py文件将可在窗口中选择。

在此处输入图片说明

这是代码:

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()
Run Code Online (Sandbox Code Playgroud)

更多例子

  • 如果删除("All Files", "*.*")呢?仍然无法文件类型和在两者之间进行切换.py.bmp有效。并且所有其他文件类型都超出了先前设置的范围。
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()
Run Code Online (Sandbox Code Playgroud)

![在此处输入图片说明

  • 只留下("All Files", "*.*")。这是我所期望的,并*.*最终生效。
filetypes = [ 
            ("Python File", "*.py"), 
            ("Image File", "*.bmp")]


Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

系统信息

  • macOS Catalina
  • 蟒蛇 3.7.5
  • Tk 版本 8.6

cdl*_*ane -2

在我的系统上:

  • macOS 莫哈维 10.4.6
  • Python 3.8.0
  • TkV 版本 8.6

我发现这个简单的解决方法让我得到了所需的行为:

filetypes = [ 
            ("All Files", "*.*"),
            ("Python File", "*.py"), 
            ("Image File", "*.bmp"),
            ]
Run Code Online (Sandbox Code Playgroud)

也就是说,通过最初提出它"All Files",然后切换到打开的对话框中的其他类型,适当地过滤文件。