无法在Tkinter中使用“索引”获得标记

时间:2019-01-24 05:43:02

标签: python tkinter

有人能回答为什么在命令self.text.mark_previous(self.text.index("insert"))下面的代码中起作用并返回正确的标记,但是self.text.mark_previous("insert")返回tk::anchor1的原因吗?只需单击文本中的某个区域,然后单击按钮即可。

import tkinter as tk

class Main(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.text = tk.Text()
        self.text.pack()
        self.strings = ["Region 1", "Region 2", "Region 3"]
        for text in self.strings:
            self.text.mark_set(text, "insert")
            self.text.mark_gravity(text, "left")
            self.text.insert("insert", "{}\n".format(text))
        for mark in self.strings:
            print(self.text.index(mark))
        self.button = tk.Button(text="Find Region", command=self.find_region)
        self.button.pack()

    def find_region(self):
        self.text.update_idletasks()
        region = self.text.mark_previous("insert") # This doesn't work. It returns tk::anchor1
        region2 = self.text.mark_previous(self.text.index("insert")) # This works
        print("You are in region {} {}".format(region, region2))

if __name__ == '__main__':
    main = Main()
    main.mainloop()

2 个答案:

答案 0 :(得分:2)

因为在与tk::anchor#相同的索引处有一个标记insert,但是在先前的位置。

最初或每当鼠标指针不在任何文本上时,currentinsert标记都位于相同的索引处,并按current的顺序紧跟insert

因此,如果您在程序开始时单击“查找区域”按钮,它将进行打印,

You are in region current Region 3

由于按顺序排列,current标记位于insert标记的先前位置(但在同一索引处),而Region 3标记位于““ 索引”的先前位置”标记到insert

据我了解,tkinter第一次单击文本框时会添加一个额外的标记tk::anchor#(我尚不知道原因),它与insert的索引相同,但是在insert标记之前(如果鼠标指针不在文本上,则在current之后)。

因此,当您根据标记名称而不是索引搜索上一个标记时,将返回同一索引上的上一个标记。您可以通过在同一索引处添加两个用户定义的标记来自己进行测试。

答案 1 :(得分:1)

答案是,tkinter在处理商标时不会将"insert"index("insert")视为精确。从正义的角度来看,它们是相同的,但是从文本小部件管理的所有其他数据的角度来看,它们是相同的。

考虑在第1行上带有文本“ Hello,world”的文本小部件。单击字母“ w”时,会发生一些事情:tkinter将添加标记“ insert”,“ tk :: anchor1”和“当前”。这些标记是有序的。如果我们要将文本小部件的内容转换为xml,则可能看起来像这样:

<text index='1.0'>Hello, </text>
<mark index='1.7' id='current'/>
<mark index='1.7' id='tk::anchor1'/>
<mark index='1.7' id='insert'/>
<text index='1.7'>world</text>

调用mark_previous("1.7")时,索引“ 1.7”指紧接所有标记的字母“ w”之前的点和 之后的点。因此,当您要求上一个标记时,它将返回“插入”,因为那是紧接字母“ w”左侧的内容。但是,如果您要求在“插入”之前的标记而不是“ 1.7”,您将得到“ tk :: anchor1”,因为那是“插入”标记左侧的标记。

您可以使用文本小部件dump方法查看标记和数据的顺序。它以列表而不是xml的形式返回信息,但是它使您可以查看文档的内部结构。

继续相同的示例(“ Hello,world”,在“ w”之前单击),dump方法返回以下内容(为清楚起见,我添加了换行符):

[
   ('text', 'Hello, ', '1.0'), 
   ('mark', 'current', '1.7'), 
   ('mark', 'tk::anchor1', '1.7'), 
   ('mark', 'insert', '1.7'), 
   ('text', 'world\n', '1.7')
]

如您所见,标记“ current”在标记“ tk :: anchor1”之前,在标记“ insert”之前,在“ world”中字母“ w”之前。