从tkinter中的Text小部件复制格式化文本

时间:2013-03-31 00:10:59

标签: python text widget format tkinter

我正在使用tkinter在Python上创建一个APA引文制作者。我使用Text小部件在生成引文后显示引文,但每当我复制文本时(使用ctrl + c快捷键,此刻)它都会丢失其格式。有没有办法从Text小部件而不是未格式化的文本中复制格式化文本(例如斜体)?

1 个答案:

答案 0 :(得分:0)

要将格式化的文本复制到剪贴板,您需要在python和支持文本格式的系统剪贴板之间的接口。我发现klembord可以在Linux和Windows上使用(Mac用户可能可以将以下解决方案改编为richxerox)。

想法是(1)将格式化的文本从文本小部件转换为html,然后转换为(2)将其添加到剪贴板:

  1. 使用text.dump(index1, index2, tag=True, text=True)可以从小部件中检索文本和标签。它返回一个类似的列表(这是下面示例中小部件的内容):

     [('text', 'Author et al. (2012). The title of the article. ', '1.0'),
      ('tagon', 'italic', '1.48'),
      ('text', 'Journal Name', '1.48'),
      ('tagoff', 'italic', '1.60'),
      ('text', ', ', '1.60'),
      ('tagon', 'bold', '1.62'),
      ('text', '2', '1.62'),
      ('tagoff', 'bold', '1.63'),
      ('text', '(599), 1–5.', '1.63'),
      ('text', '\n', '1.74')]
    

    因此,很容易使用字典将每个('tagon/off', tagname)对与相应的html标签相关联并将小部件内容转换为html。

  2. klembord.set_with_rich_text(txt, rich_txt)将字符串txt及其html格式的等效内容放入剪贴板。

这是一个完整的示例(在Linux上经过测试,我能够从文本小部件中复制文本并将其粘贴到具有格式的文字处理器中)

import tkinter as tk
import klembord

root = tk.Tk()
text = tk.Text(root)
text.pack(fill='both', expand=True)

text.tag_configure('italic', font='TkDefaultFont 9 italic')
text.tag_configure('bold', font='TkDefaultFont 9 bold')

TAG_TO_HTML = {
    ('tagon', 'italic'): '<i>',
    ('tagon', 'bold'): '<b>',
    ('tagoff', 'italic'): '</i>',
    ('tagoff', 'bold'): '</b>',
}

def copy_rich_text(event):
    try:
        txt = text.get('sel.first', 'sel.last')
    except tk.TclError:
        # no selection
        return "break"
    content = text.dump('sel.first', 'sel.last', tag=True, text=True)
    html_text = []
    for key, value, index in content:
        if key == "text":
            html_text.append(value)
        else:
            html_text.append(TAG_TO_HTML.get((key, value), ''))
    klembord.set_with_rich_text(txt, ''.join(html_text))
    return "break"  # prevent class binding to be triggered

text.bind('<Control-c>', copy_rich_text)

text.insert("1.0", "Author et al. (2012). The title of the article. ")
text.insert("end", "Journal Name", "italic")
text.insert("end", ", ")
text.insert("end", "2", "bold")
text.insert("end", "(599), 1–5.")

root.mainloop()