INTRODUCTION |
So far we have only seen a programs with a single strand of events, where one statement after another is executed, with possible ramifications and repetitions. However, when you click a mouse button, for instance, while your program is being executed, you cannot be sure where your program is located at the time. In order to capture the clicks in the program we have to introduce a new programming concept called event control. The principle is as follows: Define a function with any name, for example onMouseHit() that is never explicitly called in the program. Then ask that your computer calls this function whenever the mouse button is clicked. So, what you are telling the program is: Whenever the mouse button is clicked, execute onMouseHit().
|
MOUSE EVENTS |
It is very easy to implement the new concept in Python. In the first event-driven program, the turtle should draw a fun figure in the main part. After this, you can decorate it by coloring certain areas with a mouse click. Write the function onMouseHit(x, y), which delivers the x- and y-coordinate of the mouse click, and then give it a flood fill by using fill(x, y) (the filling of a closed region).
from gturtle import * def onMouseHit(x, y): fill(x, y) makeTurtle(mouseHit = onMouseHit) hideTurtle() addStatusBar(30) setStatusText("Click to fill a region!") repeat 12: repeat 6: forward(80) right(60) left(30)
|
MEMO |
Technically, the concept of event-driven programming is implemented by writing a function to be called whenever the event occurs. You inform the system which function this is by passing the name of your function to makeTurtle(). Here you are using the notation parameter_name = parameter_value. |
DRAWING WITH A MOUSE CLICK |
from gturtle import * def onMouseHit(x, y): setPos(x, y) repeat 6: dot(40) forward(60) back(60) right(60) makeTurtle(mouseHit = onMouseHit) speed(-1) |
MEMO |
The program has a flaw: If you click again while the turtle is still drawing a star, it will not finish that star but will immediately begin drawing the new star. However, it also continues to execute the commands of the old star, and so the new star is drawn incorrectly. This wrong behavior is apparently due to the fact that every time you click, the function onMouseHit() it is called and executed, even if the previous execution is not done yet. In order to prevent this from happening, you can use the parameter named mouseHitX instead of mouseHit. |
TURTLE CHASING THE MOUSE |
from gturtle import * def onMouseMoved(x, y): setHeading(towards(x, y)) forward(10) makeTurtle(mouseMoved = onMouseMoved) speed(-1) |
MEMO |
Besides mouseHit and mouseHitX there are other parameters of makeTurtle() at your disposal with which you can detect mouse events. Instead of x, y they use event, from which you can determine the coordinates of the mouse event.
You can also use multiple parameters simultaneously, for example the two functions onMousePressed() and onMouseDragged(): makeTurtle(mousePressed = onMousePressed, mouseDragged = onMouseDragged) You can find out which mouse button was pressed with isLeftMouseButton() or isRightMouseButton(). There is an important difference between these events and mouseHit: the movement of the turtle is not visible during the execution of the function. Therefore, you should either set the turtle on high speed with speed(-1), hide it with hideTurtle(), or execute the code for its movement in the main part of the program. |
KEY EVENTS |
from gturtle import * LEFT = 37 RIGHT = 39 UP = 38 DOWN = 40 def onKeyPressed(key): if key == LEFT: setHeading(-90) elif key == RIGHT: setHeading(90) elif key == UP: setHeading(0) elif key == DOWN: setHeading(180) makeTurtle(keyPressed = onKeyPressed) wrap() while True: forward(10) |
EXERCISES |
|
EXTRA MATERIAL |
YOUR PERSONAL MOUSE IMAGE |
You can now decorate the tracking program shown above with cuteturtle or your own mouse figure. Make sure that the turtle always moves to the mouse by using moveTo(). from gturtle import * def onMouseMoved(x, y): moveTo(x, y) makeTurtle(mouseMoved = onMouseMoved) setCustomCursor("sprites/cutemouse.gif") speed(-1) |
MEMO |
By using speed(-1) you prevent the turtle from animating so that drawing with moveTo() gets faster. Possible parameters of setCursor():
The sprites directory in the path indication of setCustomCursor() is in the same directory as your program
[more...
It can also be a subdirectory in the directory gamegrid in User Home. |