Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How draw a dot on canvas on click event Tkinter Python

I have the following piece of code that takes an image within a canvas and then whenever I click the paint function draws a dot over it.

Everything is working fine except that the paint function is not working as expected.

Desirable output

Click event draws a dot. No need to drag the on click event

Actual output

I have to drag the on mouse click event to see a drawing on the canvas.

I guess there might be a slight problem with the paint function. However, I haven't been able to know what it is exactly.

from tkinter import *
from PIL import Image, ImageTk


class Main(object):

    def __init__(self):
        self.canvas = None

    def main(self):
        master = Tk()

        # Right side of the screen / image holder
        right_frame = Frame(master, width=500, height=500, cursor="dot")
        right_frame.pack(side=LEFT)

        # Retrieve image
        image = Image.open("./image/demo.JPG")
        image = image.resize((800, 700), Image.ANTIALIAS)
        photo = ImageTk.PhotoImage(image)

        # Create canvas
        self.canvas = Canvas(right_frame, width=800, height=700)
        self.canvas.create_image(0, 0, image=photo, anchor="nw")
        self.canvas.pack()
        self.canvas.bind("<B1-Motion>", self.paint)

        mainloop()

    def paint(self, event):
        python_green = "#476042"
        x1, y1 = (event.x - 1), (event.y - 1)
        x2, y2 = (event.x + 1), (event.y + 1)
        self.canvas.create_oval(x1, y1, x2, y2, fill=python_green, outline=python_green, width=10)


if __name__ == "__main__":
    Main().main()

Fix:

Added these two methods:

def on_button_press(self, event):
    self.x = event.x
    self.y = event.y

def on_button_release(self, event):
    python_green = "#476042"
    x0,y0 = (self.x, self.y)
    x1,y1 = (event.x, event.y)

changed canvas to this:

self.canvas.bind("<ButtonPress-1>", self.on_button_press)
self.canvas.bind("<ButtonRelease-1>", self.on_button_release)
like image 906
Fran Martinez Avatar asked Nov 30 '25 06:11

Fran Martinez


1 Answers

When you only click and don't move the mouse, B1-Motion isn't triggering.

To bind to mouse press (as well as mouse moving), you can add self.canvas.bind("<ButtonPress-1>", self.paint) before the mainloop.

like image 73
SneakyTurtle Avatar answered Dec 01 '25 20:12

SneakyTurtle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!