另存为文件对话框 - 如何不允许覆盖

save as file dialog - how to not allow overwrite

我正在尝试在 tkinter 中创建一个保存文件对话框。我需要保存文件名以备后用。但是,我不希望文件对话框接受选择一个已经存在的文件名。

到目前为止我只有这个:

from tkinter import filedialog

my_file = filedialog.asksaveasfilename(defaultextension = ".myfile", 
                                       filetypes = [("MY SUPER FILE", ".myfile"), 
                                                    ("All files", ".*")])

一种可能是获取文件名,检查它是否存在(使用 os.path.isfile),如果已经有同名文件,则再次询问用户新名称。但是,tkinter 文件对话框询问用户 "file already exists. do you want to overwrite?"。因此,如果稍后我告诉用户我不接受文件名选择,这似乎会让人感到困惑。有没有办法强制 tkinter filedialog 不向用户询问覆盖?

编辑:根据答案中的建议,我尝试制作自己的保存文件对话框。

我基本上只在 tkinter 保存对话框中添加了警告:

class MySaveFileDialog(filedialog.FileDialog):

""" File save dialog that does not allow overwriting of existing file"""
def ok_command(self):
    file = self.get_selection()
    if os.path.exists(file):
        if os.path.isdir(file):
            self.master.bell()
            return
        messagebox.showarning("The current file name already exists. Please give another name to save your file.")
    else:
        head, tail = os.path.split(file)
        if not os.path.isdir(head):
            self.master.bell()
            return
    self.quit(file)

所以,它看起来很简单。然后我想:我需要创建自己的 asksaveasfilename 函数。 我去查看来源:

def asksaveasfilename(**options):
"Ask for a filename to save as"

return SaveAs(**options).show()

嗯..我需要看看 SaveAs 在做什么。

class SaveAs(_Dialog):
    "Ask for a filename to save as"

    command = "tk_getSaveFile"

Aaannddd...我迷路了。我不明白这些部分是如何组合在一起的。 'SaveAs' 只有命令 tk_getSaveFile。这里如何使用 SaveFileDialog?我如何制作自己的 myasksaveasfilename 函数?

没有这个选项。如果你想摆脱安全问题,那么你将不得不编写自己的文件对话框。

如果您查看 filedialog.py,您会发现该对话框是在 Python 中实现的。因此,您所要做的就是扩展 class SaveFileDialog 并使用不允许 select 现有文件名的方法覆盖方法 ok_command()

您可以使用大部分现有代码,只需更改一些文本即可实现您的目标。

我还没有测试过,但这段代码应该可以工作:

def ok_command(self):
        file = self.get_selection()
        if os.path.exists(file):
            if os.path.isdir(file):
                self.master.bell()
                return
            d = Dialog(self.top,
                       title="Overwrite Existing File",
                       text="You can't overwrite an existing file %r. Please select a new name." % (file,),
                       bitmap='error',
                       default=0,
                       strings=("OK",))
            return
        else:
            head, tail = os.path.split(file)
            if not os.path.isdir(head):
                self.master.bell()
                return
        self.quit(file)

为了完成 Aaron 所说的内容,这里是 ok_command 的当前代码:

def ok_command(self):
        file = self.get_selection()
        if os.path.exists(file):
            if os.path.isdir(file):
                self.master.bell()
                return
            d = Dialog(self.top,
                       title="Overwrite Existing File Question",
                       text="Overwrite existing file %r?" % (file,),
                       bitmap='questhead',
                       default=1,
                       strings=("Yes", "Cancel"))
            if d.num != 0:
                return
        else:
            head, tail = os.path.split(file)
            if not os.path.isdir(head):
                self.master.bell()
                return
        self.quit(file)

您可以使用 tkFileDialog.asksaveasfilename(confirmoverwrite=False)
实现此目的 这是一个模型:

import tkFileDialog 
import tkMessageBox as mbox
class Example():
    proceed = False
    while proceed == False:
        dlg = tkFileDialog.asksaveasfilename(confirmoverwrite=False)
        fname = dlg
        if fname != '':
            try:
                f = open(fname, "r")
                f.close()
                mbox.showerror("Error","File exists - Choose another file name")
            except:
                mbox.showinfo("Info","File does not exist - Continue")
                proceed = True
        else:
            break
    print("Finished")