如何在 python 中使用鼠标拖动打印在图像(canvas 中)上的文本?

How to drag text which is printed over Image (in canvas) using mouse in python?

我想在 canvas 中添加一个 拖动文本功能 以使用鼠标更改文本的位置。

from PIL import Image,ImageFont,ImageDraw,ImageTk
import tkinter as tk

root = tk.Tk()
root.title('Demo')
root.geometry('400x50')

def func_image():

    img_window = tk.Toplevel()
    img_window.grab_set()

    photo = Image.open(r'E:\side_300.png')
    wi,hi = photo.size
    fonty = ImageFont.truetype('arial.ttf',18)
    draw = ImageDraw.Draw(photo)
    draw.text((50,50),text=text.get(),fill='red',font=fonty)
    new_photo = photo
    can_photo = ImageTk.PhotoImage(new_photo)

    canvas = tk.Canvas(img_window,height=500,width=500)
    canvas.pack(anchor='n')
    canvas.create_image(wi/2,hi/2,image=can_photo,anchor='center')
    img_window.mainloop()

lbl_text = tk.Label(root,text='Enter Text :')
lbl_text.grid(row=0,column=0)

text = tk.Entry()
text.grid(row=0,column=1)

btn = tk.Button(root,text='Click Me',command=func_image)
btn.grid(row=0,column=2)

root.mainloop()

当您 运行 代码时,它将首先打开一个名为 'Demo' 的 window,其中包含一个输入框和一个按钮。
当您在输入框中输入一些文本后单击按钮 'Click Me' 时,它将转到函数 func_image 并打开一个新的 window 其中包含一个 canvas 填充 new_image.

快速免责声明:我对 PIL 没有太多经验,所以我不知道如何删除已经绘制的文本。也许你可以自己弄清楚。但除此之外,我还知道一些关于 tkinter 的事情。我的想法如下:

将函数绑定到 <B1-motion> 事件(按钮 1 被按住并移动),它将不断获取鼠标在 window 内的位置并在该位置绘制新文本,同时删除以前的文本。

    import...
    ...

    def func_image():
        img_window = tk.Toplevel()
        ...
        ...
        draw = ImageDraw.Draw(photo)
        draw.text((50,50),text=text.get(),fill='red',font=fonty)
        ...
        def move_text(event):
            # here you would delete your previous text
            x = event.x
            y = event.y
            draw.text((x,y),text=text.get(),fill='red',font=fonty

        img_window.bind('<B1-Motion>', move_text)

话虽这么说,但我认为使用 Canvas.create_text(更多关于 effbot.org)在图像上写下您的文字会更好。在 Canvas 上拖动文本真的很容易,这里有一个小例子:

import tkinter as tk

root = tk.Tk()

def change_position(event):
    x = event.x
    y = event.y

    # 20x20 square around mouse to make sure text only gets targeted if the mouse is near it
    if text in c.find_overlapping(str(x-10), str(y-10), str(x+10), str(y+10)):
        c.coords(text, x, y)  # move text to mouse position

c = tk.Canvas(root)
c.pack(anchor='n')

text = c.create_text('10', '10', text='test', fill='red', font=('arial', 18))  # you can define all kinds of text options here
c.bind("<B1-Motion>", change_position)

root.mainloop()