python 在通过事件创建了一个tkinter文本小工具后,如何将插入光标定位在鼠标指针下?

ryoqjall  于 2023-02-07  发布在  Python
关注(0)|答案(3)|浏览(127)

我希望用户能够编辑画布文本项。由于画布文本项的功能比文本小部件少,我希望使用文本小部件进行编辑。因此,当编辑开始时,通过鼠标双击事件,我在画布文本项上打开一个新的画布窗口项,并在其中放置一个文本小部件,然后将画布文本项的文本插入到文本小部件中。当然,文本小部件的插入光标现在位于文本小部件的末尾,但我希望它位于鼠标双击发生的位置,我该怎么做呢?
这是我的代码:

import tkinter as tk

def edit_text(event):
    coords = canvas.bbox(canvas_text)
    text_ref = tk.Text(root, font=("Courier", 10))
    canvas_window = canvas.create_window(coords[0], coords[1], window=text_ref, anchor="nw")
    text_ref.bind("<Escape>", lambda event: store_edits(text_ref, canvas_window))
    text_ref.insert("1.0", canvas.itemcget(canvas_text, "text"))
    text_ref.focus_set()

def store_edits(text_ref, canvas_window):
    canvas.itemconfig(canvas_text, text=text_ref.get("1.0", "end"))
    canvas.delete(canvas_window)
    del text_ref

root = tk.Tk()
canvas = tk.Canvas(root)
canvas.grid()

canvas_text = canvas.create_text(100, 100, text="aaa\n456\n123\n123\n456\n123\nbbb\n", font=("Courier", 10))
canvas.tag_bind(canvas_text, "<Double-Button-1>", edit_text)

root.mainloop()

我问,因为我相信我不是第一个有这个问题。

i86rm4rw

i86rm4rw1#

可以对文本小部件使用"@x,y"的索引,并且可以根据传入的信息计算正确的x,y。诀窍在于需要等到文本小部件可见时才能使用索引,因为tkinter在此之前无法计算索引。
它可能看起来像这样:

def edit_text(event):
    coords = canvas.bbox(canvas_text)
    ...
    x = event.x - coords[0]
    y = event.y - coords[1]
    canvas.after_idle(lambda: text_ref.mark_set("insert", f"@{x},{y}"))

除非考虑到文本小部件有一个边框和突出显示厚度,导致文本与画布上的文本略有偏移,否则计算可能会有一些偏差,但这是总体思路。

b1payxdu

b1payxdu2#

我找到了一个简单的解决方案:用户不必使用鼠标双击,而是使用鼠标三次单击。与计算光标位置的复杂想法相比,这是非常容易的。

dgsult0t

dgsult0t3#

你可以简单地启用或禁用Text小部件,但是Double-Button-1已经被用来标记单词了,所以你可能需要选择其他绑定。

import tkinter as tk

def edit_text(event):
    state_txt = txt_box['state']
    if state_txt == 'disabled':
        txt_box.config(state="normal")
    elif state_txt == 'normal':
        txt_box.config(state="disabled")

root = tk.Tk()
txt_box = tk.Text(root, font=("Courier", 10))
txt_box.grid()

txt_box.insert('1.0', "aaa\n456\n123\n123\n456\n123\nbbb\n")
txt_box.config(state="disabled")
txt_box.bind("<Double-Button-1>", edit_text)

root.mainloop()

相关问题