在 tkinter 文本中查找使用 window_create 创建的元素的索引

find index of elements created with window_create inside tkinter Text

我使用 window_create 在文本元素内创建交互式按钮。按钮代表随机值或静态值,我希望能够编译文本元素的内容并用它们各自的值替换按钮。但是,我找不到任何按钮在哪里。

我试过 self.text.get("1.0",tk.END),但它只有 returns 文本,不包括按钮元素

按钮元素是这样创建的:

btn_text = tk.StringVar()
value = StaticValue('static', btn_text, self.custom_val_veiwer, idx)
button = tk.Button(self.text, 
                        textvariable=btn_text, command=lambda v=value: 
                        self.veiw_custom_val(None, val=v))
btn_text.set('static')
self.custom_vals.append(value)
self.text.window_create(tk.INSERT, window=button)

编辑: 如果您想重现问题,请使用此:

import tkinter as tk

root = tk.Tk()
text = tk.Text(root)
text.pack()

text.insert(tk.END, 'before button')

button = tk.Button(text, text='button')
text.window_create(tk.END, window=button)

text.insert(tk.END, 'after button')
print(text.get("1.0",tk.END))
root.mainloop()

注意按钮如何出现在文本字段中,但未打印出来

(输出是 before buttonafter button 我想要类似 before button<button>after button 的东西或告诉我在索引 y 处的 x 行有一个按钮的函数)

没有什么能完全满足您的需求,但只需几行代码即可获取所点击按钮的索引。

我要做的是让按钮将对自身的引用作为参数传递给命令。这需要分两步制作按钮,因为您无法在按钮创建之前引用它。

button = tk.Button(text, text="button")
button.configure(command=lambda button=button: handle_click(button))

在按钮调用的函数中,您可以使用文本小部件dump命令获取所有windows的列表,并从中找到按钮的索引。 dump 命令将 return 一个元组列表。每个元组都有一个键(在本例中为 "window")、window 名称和 window 的索引。您可以遍历该命令的结果以找到传递给该函数的按钮的索引。

def handle_click(button):
    for (key, name, index) in text.dump("1.0", "end", window=True):
        if name == str(button):
            print("you clicked on the button at index {}".format(index))
            break

例子

这是一个人为的例子,添加了几个按钮。单击该按钮将在标签中显示该按钮的索引。请注意,即使您手动编辑文本小部件以更改按钮的索引,它仍将继续工作。

import tkinter as tk

root = tk.Tk()
text = tk.Text(root)
label = tk.Label(root)
label.pack(side="top", fill="x")
text.pack(side="top", fill="both", expand=True)

def handle_click(button):
    for (key, name, index) in text.dump("1.0", "end", window=True):
        if name == str(button):
            label.configure(text="You clicked on the button at {}".format(index))
            break

for word in ("one", "two", "three", "four", "five"):
    text.insert("end", word + "\n")
    button = tk.Button(text, text="click me")
    button.configure(command=lambda button=button: handle_click(button))
    text.window_create("insert-1c", window=button)

tk.mainloop()