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

Why doesn't save() write to file first time?

我正在制作一个文本编辑器,我正在研究 save/save-as 按钮,发现了一些我最初认为有用但后来发现有问题的东西。菜单中的保存和另存为按钮不会将文本小部件中的文本保存到文件中,而只是创建一个。我已经输入了两个函数 self.f1.write(text) 但只有在点击几下之后文本才会真正保存。这不是时间问题,因为我等了大约五分钟,但仍然没有用。我在 Yosemite 上有一个 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()

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

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

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" 的意思(结束,减去一个字符)。