Python Tkinter 文本编辑器不将字体保存到文本文件

Python Tkinter text editor does not save font to text file

目前,我正在使用 python 和 tkinter 开发 GUI 文本编辑器。感谢 SO 的优秀人员(感谢 Rinzler),我设法修改了文本的字体。但是,我无法将字体和字体大小保存到 txt 文件中。 我知道这应该是可能的,因为记事本可以修改并保存具有指定字体的 txt 文件。

这是保存到文件的代码:

def file_saveas():
    filename = tkFileDialog.asksaveasfile(mode='w', defaultextension=".txt")
    if filename is None: # asksaveasfile return `None` if dialog closed with "cancel".
        return
    text2save = str(textPad.get(1.0, END)) # starts from `1.0`, not `0.0`
    filename.write(text2save)
    filename.close()
    print filename

这是更改字体的代码(由 Rinzler 提供):

def choose_font():
global root, textPad # I hate to use global, but for simplicity

t = Tkinter.Toplevel()
font_name = Tkinter.Label(t, text='Font Name: ')
font_name.grid(row=0, column=0, sticky='nsew')
enter_font = Tkinter.Entry(t)
enter_font.grid(row=0, column=1, sticky='nsew')
font_size = Tkinter.Label(t, text='Font Size: ')
font_size.grid(row=1, column=0, sticky='nsew')
enter_size = Tkinter.Entry(t)
enter_size.grid(row=1, column=1, sticky='nsew')

# associating a lambda with the call to text.config()
# to change the font of text (a Text widget reference)
ok_btn = Tkinter.Button(t, text='Apply Changes',
                   command=lambda: textPad.config(font=(enter_font.get(), 
                   enter_size.get())))
print font
ok_btn.grid(row=2, column=1, sticky='nsew')
done = Tkinter.Button(t, text='Get rid of Pushy!', command=t.destroy)
done.grid(row=4, column=1, sticky='nsew')
# just to make strechable widgets
# you don't strictly need this
for i in range(2):
    t.grid_rowconfigure(i, weight=1)
    t.grid_columnconfigure(i, weight=1)
t.grid_rowconfigure(2, weight=1)

最后,这是读取字体和其他配置信息的代码:

font = (fontname, size)
textPad.config(
    borderwidth=0,
    font=font ,
    foreground="green",
    background="black",
    insertbackground="white", # cursor
    selectforeground="blue", # selection
    selectbackground="#008000",
    wrap="word", 
    width=64,
    undo=True, # Tk 8.4
    )

我在互联网上搜索过,但没有找到关于为什么不保存字体和文本大小的任何答案。任何帮助将不胜感激。

我正在使用 python 2.7.7,Tkinter,这是 运行 在 Windows 7.

任何帮助操作 rtf 文件也会有帮助(目前,我看到的是标签而不是结束格式)。

tkinter 不支持此功能。您必须选择支持字体的文件格式(rtf、.docx、.html 等),将小部件中的数据转换为这种格式,然后将其写入文件。

记事本的编辑器只能有自定义字体和大小window,它不会将其保存到文件中,它只是记住用户的自定义设置,并将它们应用到它的window 使用时。

tkinter 文本小部件无法将格式保存为另一种格式,我尝试将其转换为 XML 以保存为 .docx,但我没有成功。我使用了我自己的格式,这是一个纯文本文件,开头有一个 'index' 的 tkinter 文本小部件标签及其行和列索引,然后是文档开始位置的标记,然后是文档。虽然这不能保存图像,并且当您在另一个文字处理器中打开它时,它会打开所有格式索引。

XML 是打开和保存 tkinter 文本内容的理想选择 - 使用 xml 解析器打开,然后使用递归函数添加带标签的文本。 (如果你想要富文本,这就像 xml 一样,是一种迭代格式 - 元素内嵌元素,所以可以像我在下面描述的 xml 那样完成,但你需要编写自己的富文本文本解析器)

    import xml.etree.ElementTree as etree

    e = etree.fromstring(string)
    #create an element tree of the xml file
    insert_iter(e)
    #call the recursive insert function
    def insert_iter(element):
      #recursive insert function
      text.insert("end", element.text, tagname)
      #insert the elements text
      for child in element:
        insert_iter(child)
        #iterate through the element's child elements, calling the recursive function for each
        text.insert("end", child.tail, tagname)
        #insert the text after the child element
      text.tag_config(tagname, **attrib)
      #configure the text

'attrib' 是一本字典,例如。 {"foreground":"red", "underline":True} 将使您插入的文本具有红色字体和黑色下划线, 'tagname'是一个随机字符串,需要你的程序自动生成

要保存文件,请创建一个函数来执行反向操作。我不会为这个使用 xml 库而烦恼 - 因为 tkinter 输出正确的格式,只需手动编写它,但一定要转义它

    from xml.sax.saxutils import escape

    data = text.dump("1.0", "end")
    print(data[0:500]) # print some of the output just to show how the dump method works
    output = ''
    #get contents of text widget (including all formatting, in order) and create a string to add the output file to
    for line in data:
      if line[0] == "text":
        #add the plain text to the output
        output += escape(line[1])
      elif line[0] == "tagon":
        #add a start xml tag, with attributes for the given tkinter tag
        name = 'font'
        attrib = ""
        tag = #the dictionary you stored in your program when creating this tag
        for key in tag:
          attrib += "%s='%s' "%(key, escape(tag[key]))
        output += "<%s %s>"%(name, attrib)
      elif line[0] == "tagoff":
        #add a closing xml tag
        output += '</%s>'%name