2

What I want to do is have the user click on somewhere on the Canvas, then click elsewhere and have a straight line drawn between the two points. I'm new to TKinter and after some googling and searching on here I'm having trouble finding a solid answer for this.

The way that I have been thinking about it, there should be an onclick event which passes the mouse coordinates on the canvas and then an onrelease event which passes those coordinates on the canvas, thus creating a line between them. This line would have to be an object that I could then remove at some point via another button but that's a separate issue.

Any help would be greatly appreciated, or even any links to articles/tutorials that may help also

2 Answers 2

9

The only thing you have to do is bind "<Button-1>" and "<ButtonRelease-1>" to the canvas:

from Tkinter import Tk, Canvas

start = None

def onclick_handler(event):
    global start
    start = (event.x, event.y)

def onrelease_handler(event):
    global start
    if start is not None:
        x = start[0]
        y = start[1]
        event.widget.create_line(x, y, event.x, event.y)
        start = None

master = Tk()
canvas = Canvas(master, width=200, height=200)
canvas.bind("<Button-1>", onclick_handler)
canvas.bind("<ButtonRelease-1>", onrelease_handler)
canvas.pack()
master.mainloop()

I don't like at all using global variables, it is much cleaner to wrap all the widgets and related functions in a class. However, as an example I think it is clear enough.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm marking this as the correct answer because I took this approach, I just wrapped it within the class I was already building so no Global variables
4

Looks something pretty starightforward for me.

Just check the documentation on Canvas here: http://effbot.org/tkinterbook/canvas.htm

And on events here: http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

And them, just type in some code like this - the class is even more complicated than a sinple hello World - two global variables would have done for simpler code:

from Tkinter import Canvas, Tk, mainloop
w = Tk()
c = Canvas(w)
c.pack()

class DrawLines(object):
    def __init__(self, canvas):
        self.canvas = canvas
        self.start_coords = None
        self.end_coords = None
    def __call__(self, event):
        coords = event.x, event.y
        if not self.start_coords:
            self.start_coords = coords
            return
        self.end_coords = coords
        self.canvas.create_line(self.start_coords[0],
                                self.start_coords[1],
                                self.end_coords[0],
                                self.end_coords[1])
        self.start_coords = self.end_coords

c.bind("<Button-1>", DrawLines(c))

mainloop()

1 Comment

Both answers are very helpful but this is closer to how I'm setting up my program. Thank you for the links as well!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.