Dealing with mouse events

When we draw in a paint program, we use a mouse as the primary input device.

There are primarily two kinds of mouse event that cause changes on the drawing canvas and are therefore of interest: 

  • Click and release
  • Click, drag, and release

There is also a third event in which we have limited interest—the mouse movements with no buttons clicked. Our interest is limited there since an unclicked motion normally does not cause any changes on the canvas.

We ignore right-click and wheel-scroll as we will not be using them in our program.

In both the preceding cases, we need to know where the mouse was first clicked and where it was released. For click and release, this could be the same location. For click, drag, and release this will normally be different locations.

Accordingly, we define four attributes to keep track of the coordinates for these two locations (see code 6.02.py):

start_x, start_y = 0, 0
end_x, end_y = 0, 0

Our immediate goal then is to bind our mouse events in such a way that any click or drag gives us the value of these four start and end coordinates.

The coordinates of the Canvas widget begin at the top-left corner ((0, 0) is the top-corner). 

The Canvas widget uses two coordinate systems:

  • The window coordinate system, which is always 0, 0 for the leftmost corner, no matter where you scroll down or up the canvas
  • The canvas coordinate system, which specifies where the items are actually drawn on the canvas

We will mostly be interested in the canvas coordinate system, but mouse events emit data on the window coordinate system. To convert from the window coordinate system to the canvas coordinate system we can use the following methods:

 canvas_x = canvas.canvasx(event.x)
canvas_y = canvas.canvasy(event.y)

Let's now modify our __init__ method to also call a method, bind_mouse. We define the bind_mouse method as follows (see code 6.02.py):

def bind_mouse(self):
self.canvas.bind("<Button-1>", self.on_mouse_button_pressed)
self.canvas.bind( "<Button1-Motion>",
self.on_mouse_button_pressed_motion)
self.canvas.bind( "<Button1-ButtonRelease>",
self.on_mouse_button_released)
self.canvas.bind("<Motion>", self.on_mouse_unpressed_motion)

We then define the first three methods that were bound just now. We ignore the unpressed motion for now by making an empty method. Remember that we are interested in getting the start and end coordinates, which are acquired as follows (see code 6.02.py):

def on_mouse_button_pressed(self, event):
self.start_x = self.end_x = self.canvas.canvasx(event.x)
self.start_y = self.end_y = self.canvas.canvasy(event.y)
print("start_x, start_y = ", self.start_x, self.start_y)

def on_mouse_button_pressed_motion(self, event):
self.end_x = self.canvas.canvasx(event.x)
self.end_y = self.canvas.canvasy(event.y)

def on_mouse_button_released(self, event):
self.end_x = self.canvas.canvasx(event.x)
self.end_y = self.canvas.canvasy(event.y)
print("end_x, end_y = ", self.end_x, self.end_y)

We have temporarily added two print statements to show these four values on the console (see code 6.02.py).

Now that we have the location of the start and end mouse events, we can act upon those events to do all kinds of activities on the canvas.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.144.56