Как переместить текст внутри холста в Tkinter

#python #tkinter #tkinter-canvas

#python #tkinter #tkinter-canvas

Вопрос:

У меня возникла проблема с перемещением текста относительно курсора мыши внутри холста.

При щелчке текста кнопкой мыши 1, а затем при перетаскивании мыши перемещается весь холст, а не текст внутри

Что я должен сделать, чтобы исправить это?

Вот мой код :

 from tkinter import* 
import tkinter as tk 

root = Tk()   
root.geometry('1000x600 500 100')
root.resizable(False,False)

def drag_start(event):
    widget = event.widget
    widget.startX = event.x
    widget.startY = event.y

def mov(event):
    widget = event.widget
    x = widget.winfo_x() - widget.startX   event.x
    y = widget.winfo_y() - widget.startY   event.y
    canvas.move(obj,x,y)
    canvas.update()

canvas=Canvas(root,width=
800,height=600,bg="red")

canvas.pack(fill=BOTH,
expand=1)

obj=canvas.create_text(100,
50,text="Object",fill=
'blue',font=('Gotham Medium',30,"bold"),anchor="nw")

canvas.tag_bind(obj,"<Button-1>",drag_start)
canvas.tag_bind(obj,'<B1-Motion>',mov)

root.mainloop()
 

Ответ №1:

Поскольку canvas.move() это относительно предыдущей позиции, вам необходимо обновить предыдущую позицию ( startX и startY ):

 def drag_start(event):
    widget = event.widget
    widget.startX, widget.startY = event.x, event.y

def mov(event):
    widget = event.widget
    widget.move(obj, event.x-widget.startX, event.y-widget.startY)
    widget.startX, widget.startY = event.x, event.y # update previous position
 

Или используйте canvas.coords() :

 def drag_start(event):
    widget = event.widget
    x, y = widget.coords(obj)
    # save the offset of the click position from the obj's top-left corner
    widget.dx, widget.dy = event.x-x, event.y-y

def mov(event):
    widget = event.widget
    widget.coords(obj, (event.x-widget.dx, event.y-widget.dy))
 

Ответ №2:

В функции была только одна небольшая ошибка mov() . Вам нужно обновить начальные позиции X и Y, как только текст был немного перемещен. В противном случае он всегда будет перемещаться относительно первой позиции и экспоненциально набирать скорость, пока не выйдет за пределы холста.

 def mov(event):
    widget = event.widget
    x = widget.winfo_x() - widget.startX   event.x
    y = widget.winfo_y() - widget.startY   event.y
    canvas.move(obj,x,y)
    widget.startX = event.x
    widget.startY = event.y
    canvas.update()
 

Это должно исправить ситуацию, и вы сможете перемещать текст.