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

时间:2015-04-07 13:28:30

标签: python python-3.x tkinter

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

到目前为止,我只有这个:

from tkinter import filedialog

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

一种可能性是获取文件名,检查文件名是否存在(使用os.path.isfile)并再次询问用户是否存在具有相同名称的文件的新名称。但是,tkinter filedialog会询问用户“文件是否已存在。是​​否要覆盖?”。因此,如果稍后我告诉用户我不接受文件名选择,这似乎令人困惑。有没有办法强制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函数?

3 个答案:

答案 0 :(得分:5)

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

如果查看filedialog.py,您会看到该对话框是用Python实现的。因此,您所要做的就是扩展类SaveFileDialog并使用不允许选择现有文件名的方法覆盖方法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)

答案 1 :(得分:0)

要完成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)

答案 2 :(得分:0)

您可以使用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")