Handling mouse events

Before we let the user draw on the canvas, we need to bind the canvas event to mouse movements and mouse click.

Drawing or adding any item on to the Canvas widget first requires that we know the coordinates of the location where the item is to be placed.

Note

The Canvas widget uses two coordinate systems to track positions:

Window coordinate system: Coordinate as expressed in relation to root window

Canvas coordinate system: Coordinate as expressed as position of item within the canvas

You can convert from window coordinates to canvas coordinates using the canvasx and canvasy methods as follows:

canx = canvas.canvasx(event.x)
cany = canvas.canvasy(event.y)

Engage Thrusters

Step 1 – binding mouse down, mouse motion, and mouse release over the canvas

Drawing any item on the canvas would begin when the user clicks the mouse button. The drawing needs to continue till the mouse is moved with the button pressed and up to the time the mouse button is released.

Thus, we need to track the position of initial mouse down event. This is to be followed by tracking the mouse movement while the button is clicked on, up to the final button release event.

Accordingly, we add the following widget binding to our canvas (see code 6.02.py):

self.canvas.bind("<Button-1>", self.mouse_down)
self.canvas.bind("<Button1-Motion>", self.mouse_down_motion)
self.canvas.bind("<Button1-ButtonRelease>", self.mouse_up)

Step 2 – calculating coordinates of mouse movement

Having bound the mouse click, mouse movement, and mouse release events, it's now time to define their corresponding callback methods.

In particular, we want the mouse_down method to give us the x and y coordinates for the first mouse click event, as follows:

def mouse_down(self, event):
	self.currentobject = None
	self.lastx = self.startx = self.canvas.canvasx(event.x)
	self.lasty = self.starty = self.canvas.canvasy(event.y)

We want to keep updating the lastx and lasty coordinates up till the mouse stops moving, as follows:

def mouse_down_motion(self, event):
	self.lastx = self.canvas.canvasx(event.x)
	self.lasty = self.canvas.canvasy(event.y)

Our mouse_up method should make the final update to our lastx and lasty coordinates, as follows:

def mouse_up(self, event):
	self.lastx = self.canvas.canvasx(event.x)
	self.lasty = self.canvas.canvasy(event.y)

The description of the code is listed as follows:

  • The mouse_down method simply initializes the values of startx, starty, lastx, and lasty to the coordinates of the mouse click position.
  • The mouse_down_motion method changes the value of lastx and lasty as the mouse motion keeps happening.
  • Finally, the mouse_up method sets the value of lastx and lasty as coordinates of the point where the mouse button is released.
  • Thus, using the three events: mouse_down, mouse_down_motion, and mouse_up, we manage to get the coordinates for starting point, coordinates for points through which the mouse pointer traverses, and the coordinates for the end point.
  • Now we can use these values to place any item on the canvas at the given coordinates.

Step 3 – updating the current mouse position label in the left tool bar

In addition, we would also like to track the motion of the mouse over the canvas, even when the mouse button is not clicked down. We need to track this to update the current mouse position in the left toolbar. This is simple, as shown in the following code snippet:

self.canvas.bind("<Motion>", self.show_current_coordinates)

def show_current_coordinates(self, event = None):
	lx = self.canvas.canvasx(event.x)
	ly = self.canvas.canvasy(event.y)
	cord = 'x: %d 
y: %d '%(lx, ly)
	self.curcoordlabel.config(text = cord)

This code will ensure that any mouse movement over the canvas updates the label in the left toolbar with the current position of mouse.

Objective Complete – Mini Debriefing

Now our Canvas widget has become responsive to mouse movements and mouse clicks. Every time we click the mouse button over the canvas and drag the mouse pointer to a new place, the values of startx, starty, lastx and lasty get updated to reflect the coordinates for the mouse movement.

Note

Together, these coordinates constitute what is called the bounding box for an item. In fact, if there are items on a canvas, you can retrieve the coordinates for any given item using the API:

canvas.bbox(item=itemName)

This returns the coordinates as a four-item tuple.

If the item name is not specified, this method returns the bounding box for all elements on the canvas.

Now that we have the coordinates available, we can think of drawing items on the canvas. We do some drawing in the next iteration.

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

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