简体   繁体   中英

Turtle Graphics Python, .mainloop()

I am programming in Python and I have a few questions that I can't find the answer to anywhere (please read all questions as they build up to my last question):

1.What Does the .mainloop() really do? I read the all the answers in Stack Overflow, I also checked the documentations explanation.

2.Does the .mainloop() always have to be at the end of a turtle program?

3.I have used .mainloop() before. My question is, if I have the ffg code:

import turtle

screen = turtle.Screen()
alex =  turtle.Turtle()
tess = turtle.Turtle()

def yes(x, y):
    alex.onclick(yes)
    print("Hello World")

tess.onclick(yes)
turtle.mainloop()

Why does alex get an action event when the function yes() is run? I know it does because the function is called, but what is actually happening? I mean the statement turtle.mainloop() is run before tess is clicked, and tess's action event is waited for in the event loop, so how does alex's event get in the event loop since its statement is run after turtle.mainloop() is run?

1.What Does the .mainloop() really do?

Turtle's mainloop() calls tkinter's mainloop() which calls Tk's Tk_MainLoop() which is surprisingly simple:

void
Tk_MainLoop(void)
{
    while (Tk_GetNumMainWindows() > 0) {
        Tcl_DoOneEvent(0);
    }
}

It handles events, one at a time, in an infinite loop while there are any main windows open. The events processed include keyboard input, button clicks, window reshapes, file I/O, network activity, timers, display refreshes and any other registered callbacks.

An excellent, one page description of mainloop can be found in the introduction to Chapter 15. Anatomy of the MainLoop in the O'Reily book Mastering Perl/Tk by Steve Lidie and Nancy Walsh. Although it's a Perl/Tk book, the information regarding mainloop is valid for Python as well. You can find this material on-line but I won't include a link here as I don't know which, if any, of the online copies are legitimately posted. But you've enough information to search for it.

2.Does the .mainloop() always have to be at the end of a turtle program?

No. It should be part of a well designed program but isn't required. Most standalone programs will include it (or something that calls it like .done() or .exitonclick() ) as the graphics window will close on completion without it. But some situations, eg. IDLE perhaps, don't need it to keep the graphics visible. A common error I find in beginner's turtle programs is creating an infinite loop of turtle activity ahead of calling mainloop() and then wondering why various events don't fire.

If you plan to have Tk process keyboard, mouse and timer events for you, then calling .mainloop() is how you get that started. In most Python/Tk programs, it's the last statement but there can be other code after it that gets executed when all the Tk windows have all closed down.

We can think of turtle programming as writing plug-in code for Tk's main loop. After we set things up, subsequent activity will be done by call back functions we've registered via on*() functions.

3.I have used mainloop() before. My question is, if I have the ffg code: ... Why does alex get an action event when the function yes() is run

When your program runs, turtles Alex and Tess are piled atop each other in the center of the window. When you click on this turtle stack, the event goes to Tess, who's both on top and has an event handler. In her event handler, Tess installs an event handler on Alex. The act of installing an event handler on Alex causes Alex to move in front of Tess, rising to the top of the stack. From now on, when you click on the turtle stack, Alex handles the events and they no longer reach Tess. We can see this clearly if we give them different colors and different event handlers:

import turtle

alex =  turtle.Turtle(shape="turtle")
alex.color("blue")

tess = turtle.Turtle(shape="turtle")
tess.color("pink")

def tess_handler(x, y):
    alex.onclick(alex_handler)
    print("Tess clicked")

def alex_handler(x, y):
    print("Alex clicked")

tess.onclick(tess_handler)

turtle.mainloop()

Clicking on the turtle stack produces:

> python3 test.py
Tess clicked
Alex clicked
Alex clicked
Alex clicked
Alex clicked
Alex clicked
Alex clicked

You could move Alex and Tess to different locations in the window and then click on them to confirm that Alex doesn't start receiving events until the first time Tess is clicked.

So mainloop() is an infinite loop that basically blocks the execution of your code at a certain point. You call it once (and only once).

so lets say:

while true:
circle.draw()
sumden.mainloop()
print "circle is being drawn"
time.sleep(0.1)

You will never see the output and print statement because there is no loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM