python 3 tkinter在标签范围终止符后继续使用自然输入的文本小部件标签

Val*_*lin 5 python tags text tkinter input

背景:

我正在尝试获得类似 MS Word 的行为。我希望紧邻标签范围末尾插入的文本自动包含在该标签的范围中。

插入标签范围内的文本的行为正如我在 MS Word 中所期望的那样。添加的彩色文本立即显示为正确的颜色、字体、样式。

使用 tag_add() 更新添加的文本时情况并非如此。您可以将更新视为视觉“打嗝”。文本作为默认文本开始并弹出到标签样式中。此外,当快速输入时,tag_add()会“丢失”标签范围。这对于我的应用程序来说是不可接受的行为。

我已经找了几天了,但找不到任何与 tkinter 如何决定如何自然地处理不断增长的标签(即没有 Text.tag_add() 或 Text.insert())相关的内容。


问题:

在决定添加新键盘输入文本的范围时,如何将 tkinter 设置为更喜欢左侧相邻索引中的标签。


演示:

我的博客上有一个演示视频以及我当前解决方案的男女混合课程。我不认为当前状态可用/功能正常。所以我需要一些可以无缝更新样式的东西。

试试吧!博客文章


所需技术:

Windows 上的 python 3+ 和 tkinter


期望的结果:

基本范围,插入在“terminal”中“l”之后

基本标签范围

下一个字符插入应继续左侧样式,就好像它在这些标记范围内一样。从默认文本到新样式没有任何视觉流行。并且应该不关心用户打字的速度。

更新了标签范围


谢谢你!

Val*_*lin 3

避免我在演示中展示的伪影的最简单方法。是将方法中的 tag_add() 绑定到根窗口“key”事件。老实说,我不确定这是为什么。但是,当绑定到根而不是文本小部件时,应用程序的行为符合预期。

对于上下文,这里是我的博客文章中的代码精简示例。我将所有检查功能分解为几行。但重要的部分是我绑定 self.master.bind('', foobar) 时的“__ init __”

查看博客上的视频演示以了解结果。

https://valtyrtriit.blogspot.com/2022/02/python-3-win10-tkinter-word-processor_22.html

请注意,“Tab”现在不会显示在事件中,因为它是导航窗口元素的保留事件。您可以打破默认绑定并重新绑定它来解决此问题。

import tkinter as tk
import re

class Document(tk.Text):
    def __init__(self, master, *args, **kewargs):
        super().__init__(*args, **kewargs)
        self.master = master
        self.master.bind("<KeyPress>", self.any_key_down)
        self.tag_add('<b>', "1.0", "1.2")
        self.tag_config('<b>', foreground='red')

    def any_key_down(self, event=None):
        print(event)
        char = re.findall(r"[a-zA-Z0-9\S ]", event.char)
        if 0 < len(char) and event.keysym not in ["BackSpace", "Escape"] or '\t' == event.char:
            insert = event.widget.index('insert-2c')
            tags = event.widget.tag_names(insert)
            for tag in tags:
                event.widget.tag_add(tag, 'insert-1c', 'insert')

root = tk.Tk()
text = Document(root, height=4)
text.pack()

text.insert("1.0", "This is helvetica font", "<b>")
text.insert("1.0", "This is terminal font", "font_term")
text.tag_config('<b>', font='Helvetica 12')
text.tag_config('font_term', font='Terminal 12')
text.insert("3.0", "This is terminal font\n", "font_term")

root.mainloop()
Run Code Online (Sandbox Code Playgroud)