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.
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)
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)
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:
mouse_down
method simply initializes the values of startx
, starty
, lastx
, and lasty
to the coordinates of the mouse click position.mouse_down_motion
method changes the value of lastx
and lasty
as the mouse motion keeps happening.mouse_up
method sets the value of lastx
and lasty
as coordinates of the point where the mouse button is released.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.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.
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.
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.
3.145.166.149