【问题标题】:Copying formatted text from Text widget in tkinter从 tkinter 中的 Text 小部件复制格式化文本
【发布时间】:2013-03-31 00:10:59
【问题描述】:

我正在使用 tkinter 在 Python 中开发一个 APA 引用生成器。我使用 Text 小部件在生成引文后显示引文,但是每当我复制文本(目前使用 ctrl+c 快捷方式)时,它都会丢失其格式。有没有办法从 Text 小部件中复制格式化文本(例如斜体)而不是无格式文本?

【问题讨论】:

标签: python text widget format tkinter


【解决方案1】:

要将格式化的文本复制到剪贴板,您需要在 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2015-07-06
    • 2019-06-14
    • 2020-09-17
    • 1970-01-01
    • 2011-03-30
    • 2015-01-28
    相关资源
    最近更新 更多