Search code examples
pythontkintertkinter-button

Tkinter : Not able to bind object to mouse drag


I am unable to bind the mouse movement to the line drawn. I currently have a button which draws lines when clicked, but the problem is i want to move these lines using the mouse ,but i keep getting error.

 from tkinter import *
 root = Tk()

 root.title('Column-seperator')
 root.geometry('800x600')

 canvas = Canvas(root,width = 480,height = 600)
 canvas.pack(padx=5,pady=5)

 line = canvas.create_line(300, 35, 300, 200, dash=(4, 2))

 btn1 = Button(root, text = 'line', bd = '5',command = line)
 btn2 = Button(root, text = 'Close', bd = '5',command = root.destroy)

 btn1.pack(side = 'top')   
 btn2.pack(side = 'top')

 

 root.bind("<B1-Motion>", line)

 root.mainloop()

And ultimately return the x-coordinates of all these lines.


Solution

  • Youre getting an error because bind expects a command, but you simply passed the return of canvas.create_line, which is an object i assume. I guess you want something like the following, however you would have to manage to exactly hit the line to move it:

    from tkinter import *
    from functools import partial
    
    
    def get_line_coords():
        # iterate over all line objects
        for line in line_storage:
            # print object (just an int as it seems), get coords for that object from canvas
            print(f"Line {line} coords: {canvas.coords(line)}")
    
    
    def create_new_line():
        # creates the line object
        line_obj = canvas.create_line(300, 35, 300, 200, dash=(4, 2))
    
        # binds the function move_line to the object, hand over the object to the function aswell (partial)
        canvas.tag_bind(line_obj, "<Button1-Motion>", partial(move_line, line_obj))
    
        # append object to list
        line_storage.append(line_obj)
    
    
    def move_line(line_obj, ev):
        # event triggered for that one object to move the object
        print(f"Moving {line_obj} to {ev.x} {ev.y}")
        # you have to play around with the offsets here as i didnt think it through
        canvas.coords(line_obj, ev.x, ev.y+35, ev.x, ev.y+200)
    
    
    root = Tk()
    
    root.title('Column-seperator')
    root.geometry('800x600')
    
    btn1 = Button(root, text='Create line', bd='5', command=create_new_line)
    btn2 = Button(root, text='Close app', bd='5', command=root.destroy)
    btn3 = Button(root, text="Get line coords", bd="5", command=get_line_coords)
    
    btn1.pack(side='top')
    btn2.pack(side='top')
    btn3.pack(side="top")
    
    canvas = Canvas(root, width=480, height=600)
    canvas.pack(padx=5, pady=5)
    
    line_storage = []
    
    root.mainloop()