簡體   English   中英

如何在 tkinter 文本框中使用帶有 html 標簽的文本,或更改它以使其在 tkinter ZD304BA20E96D873411 中工作?

[英]How can I use text with html tags in a tkinter text box, or change it so that it works in a tkinter label?

我收到了很多文本,並被要求在 tkinter 應用程序中顯示它。 文本有很多 html 標簽,如<em> ... <\em><sup> ... <\sup> ,其中文本需要斜體或上標。

tkinter 中是否有內置方法可以做到這一點? 如果沒有,是否甚至可以編寫一個 function 來例如將<em>標簽之間的所有文本斜體,然后刪除標簽?

我知道我可以通過執行以下操作來刪除標簽:

for tag in ["<em>", "<\em>", "<sup>", "<\sup>"]:
    text = "".join(text.split(tag))

但我真的需要,至少,在刪除它們之前,將<em>標簽之間的文本斜體。

我是 tkinter 的新手,我一直在看很多教程和谷歌搜索解決方案,但似乎 tkinter 不能自然地使用 html 標簽,我可以找到任何解決方案。

編輯:

我需要在常規的 tkinter 文本小部件中顯示它。

我知道我可以使用 tkinter 的font方法和slant=italic將文本框中的文本設置為斜體。 我只需要知道一種將參數設置為<em>標記之間的所有內容的方法。

所以,我在過去的幾天里自己解決了這個問題。 首先,您在文本中找到要斜體的位置,從文本中刪除 html 標記,就像 go 一樣,接下來您必須將無標記文本放入文本小部件中,然后您必須識別小部件的文本以斜體顯示。

這有點挑剔,因為識別文本小部件文本中的點需要十進制輸入,其中小數點前的數字表示行號,小數點后的數字表示該行中字符的索引。 這意味着您需要識別每個索引的行號,因此您需要一種方法來准確地知道一行結束和另一行開始的位置。 此外,第 2 行字符 4 是2.4 ,第 2 行字符 40 是2.40所以Float(f"{line_number}.{character_number}")將不起作用,因為它會刪除任何尾隨零,你必須使用Decimal(f"{line_number}.{character_number}")

例如,在文本alphabet = 'abcd efg hijk\nlmnop qrs tuv wx yz'中,如果要將“h”到“p”的所有字母都斜體,首先必須獲得“h”的索引才能開始斜體在start = alpha.find("h") ,然后在 p 之后停止斜體end = alphabet.find("p") + 1 接下來,您必須找到起點和終點在哪一行,並將索引(分別為 9 和 19)轉換為十進制格式(1.9 和 2.5):

start_line = alphabet[:start].count("\n") + 1
end_line = alphabet[:end].count("\n") + 1
line_start_point = len(alphabet[alphabet[:start].rfind("\n") + 1: start])
line_end_point = len(alphabet[alphabet[:end].rfind("\n") + 1: end])
start_point = Decimal(f"{start_line}.{line_start_point}")
end_point = Decimal(f"{end_line}.{line_end_point}")

無論如何,這是我最終用來刪除不必要的<sup>...</sup>標記和它們之間的任何內容,並將<em>...</em>標記之間的所有內容斜體的所有代碼:

from decimal import Decimal
from tkinter import *
from tkinter import font

def em_points(text):
    suppat = re.compile(r'<sup>\w*</sup>')
    suppatiter = suppat.findall(text)
    if suppatiter:
        for suptag in suppatiter:
            text = "".join(text.split(suptag))
    finds = list()
    if "<em>" in text:
        find_points = list()
        emcount = text.count("<em>")
        for _ in range(emcount):
            find_open = text.find("<em>")
            text = text[:find_open] + text[find_open + 4:]
            find_close = text.find("</em>")
            text = text[:find_close] + text[find_close + 5:]
            find_points.append([find_open, find_close])
        for points in find_points:
            finds.append(text[points[0]: points[1]])
    return [text, finds]

def italicize_text(text_box, finds):
    italics_font = font.Font(text_box, text_box.cget("font"))
    italics_font.configure(slant="italic")
    text_box.tag_configure("italics", font=italics_font)
    text_in_box = text_box.get(1.0, END)
    used_points = list()
    for find in finds:
        if find not in text_in_box:
            raise RuntimeError(f"Could not find text to italicise in textbox:\n    {find}\n    {text_in_box}")
        else:
            start_point = text_in_box.find(find)
            end_point = start_point + len(find)
            found_at = [start_point, end_point]
            if found_at in used_points:
                while found_at in used_points:
                    reduced_text = text_in_box[end_point:]
                    start_point = end_point + reduced_text.find(find)
                    end_point = start_point + len(find)
                    found_at = [start_point, end_point]
            used_points.append(found_at)
            text_to_startpoint = text_in_box[:start_point]
            text_to_endpoint = text_in_box[:end_point]
            start_line = text_to_startpoint.count("\n") + 1
            end_line = text_to_endpoint.count("\n") + 1
            if "\n" in text_to_startpoint:
                line_start_point = len(text_in_box[text_to_startpoint.rfind("\n") + 1: start_point])
            else:
                line_start_point = start_point
            if "\n" in text_to_endpoint:
                line_end_point = len(text_in_box[text_to_endpoint.rfind("\n") + 1: end_point])
            else:
                line_end_point = end_point
            start_point = Decimal(f"{start_line}.{line_start_point}")
            end_point = Decimal(f"{end_line}.{line_end_point}")
            text_box.tag_add("italics", start_point, end_point)

em_text = em_points(text)
clean_text = em_text[0]
em_list = em_text[1]

text_box = Text(root, width=80, height=5, font=("Courier", 12))
text_box.insert(1.0, clean_text)
italicize_text(text_box, em_list)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM