为啥 save() 第一次不写入文件?

Posted

技术标签:

【中文标题】为啥 save() 第一次不写入文件?【英文标题】:Why doesn't save() write to file first time?为什么 save() 第一次不写入文件? 【发布时间】:2015-10-26 06:31:47 【问题描述】:

我正在制作一个文本编辑器,我正在处理保存/另存为按钮,并且发现了一些我最初认为可行但后来发现问题的东西。菜单中的保存和另存为按钮不会将文本小部件中的文本保存到文件中,而只是创建一个。我已经输入了两个函数self.f1.write(text),但只有在点击几下后,文本才会真正保存。这不是时间问题,因为我等了大约五分钟,但它仍然没有工作。我在优胜美地有一台 Mac。

为什么不起作用?

这是脚本:

#modules
from Tkinter import *
from Tkinter import TclError
import tkFont
import tkMessageBox
import tkFileDialog


class Main(object):
    def __init__(self, root):
        root.title("PyText")
        #menu for the file cascade
        self.m1=Menu(root)

        self.appmenu = Menu(self.m1, name="apple", tearoff=0)
        self.m1.add_cascade(menu=self.appmenu)
        self.appmenu.add_command(label="About PyText")
        self.appmenu.add_separator()

        self.fm=Menu(self.m1, tearoff=0)
        self.fm.add_command(label="New", command=self.saveas)
        self.fm.add_command(label="Open", accelerator="Cmd+O", command=self.open)
        #these two don't work first time...
        self.fm.add_command(label="Save", accelerator="Cmd+S", command=self.save)
        self.fm.add_command(label="Save As", command=self.saveas)

        self.fm.add_separator()

        self.fm.add_command(label="Exit", command=root.quit)

        self.m1.add_cascade(label="File", menu=self.fm)

        root.config(menu=self.m1)

        #Main text widget
        self.t1=Text(root)
        self.t1.config(width=90, height=40, undo=True, highlightbackground="black", cursor="ibeam")
        self.t1.grid(row=1)


    # Here is the problem.
    # this command creates the file but does not
    # save the text to the file.
    def saveas(self):
        text = self.t1.get(0.0, END)
        self.savelocation=tkFileDialog.asksaveasfilename()
        self.file=open(self.savelocation, "w+")
        self.file.write(text)

    # this also has
    # the same problem. Once save as has
    # been called, it does not save when pressed
    # in first click but after a few clicks it
    # finaly saves.
    def save(self):
        try:
            text = self.t1.get(0.0, END)
            self.f1=open(self.file, "w+")
            self.f1.write(text)
        except IOError:
            text = self.t1.get(0.0, END)
            self.f1=open(self.savelocation, "w+")
            self.f1.write(text)
        except Exception:
            tkMessageBox.showinfo("Error", "Please save-as first.")
            raise

    #works fine!
    def open(self):
        self.file=tkFileDialog.askopenfilename()
        self.OpenFile=file(self.file) # get a file handle
        self.ReadFile= self.OpenFile.read() # read the file to variable
        self.OpenFile.close() # close file handle
        self.t1.delete(0.0, END)
        self.t1.insert(END, self.ReadFile)

root = Tk()
app = Main(root)
root.mainloop()

【问题讨论】:

使用 close() 或上下文管理器。 我的意思是在保存后关闭文件,使用 close() 或上下文管理器,即with file as f: 感谢您为我节省了很多时间!你能把它放在答案中以便我接受吗? 如果“#these two don't work first time”表示你试图多次保存到同一个文件,问题是打开文件为“w+”,这意味着读写.如果您想将记录添加到现有文件,请使用 "a"=append to an existing file 打开它。 【参考方案1】:

您的代码正在保存数据。但是,您并没有关闭文件并且 python 缓冲区输出,因此磁盘上的文件实际上可能没有任何数据,直到某些原因导致文件关闭(例如正常退出程序)。

简单的解决方案是确保在写入文件后关闭文件,最简单的方法是使用open 和with 语句。

def save(self):
    try:
        with open(self.file, "w+") as f1:
            texts = self.t1.get("1.0", "end-1c")
            f1.write(text)
    ...

在上面的代码中,当with 块完成时,保证文件被关闭并且上下文被刷新到磁盘。

注意:您对索引0.0 的使用不正确。索引必须是字符串,并且第一个字符是"1.0" 而不是"0.0"。此外,Tkinter 总是在文本小部件中添加一个额外的换行符。如果您想要用户输入的内容,您需要获取除最后一个字符之外的所有字符,这就是"end-1c" 的意思(结束,减去一个字符)。

【讨论】:

以上是关于为啥 save() 第一次不写入文件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Stream.CopyTo 不直接写入文件?

写入二进制文件并用各种程序打开后,为啥结果不符合预期?

为啥我的 Linux 版本的 logstash 不通过换行写入输出文件

如何将图像的名称及其坐标写入 save.txt 文件?

java中输出流不关闭为啥不能写入

ansys vwrite命令 为啥每次写入都会将原来的数据删除,如何继续写入,不删除原数据??