简体   繁体   English

Turtle Graphics Python,.mainloop()

[英]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): 我正在用Python编程,我有几个问题无法在任何地方找到答案(请阅读所有问题,以解决我的最后一个问题):

1.What Does the .mainloop() really do? 1 .mainloop()真正作用是什么? I read the all the answers in Stack Overflow, I also checked the documentations explanation. 我阅读了Stack Overflow中的所有答案,还检查了文档说明。

2.Does the .mainloop() always have to be at the end of a turtle program? .mainloop()一定总是在乌龟程序的末尾吗?

3.I have used .mainloop() before. 3.我以前用过.mainloop() My question is, if I have the ffg code: 我的问题是,如果我有ffg代码:

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? 为什么在运行yes()函数时alex会收到一个动作事件? 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? 我的意思是说语句turtle.mainloop()在单击turtle.mainloop()之前运行,并且tess的action事件在事件循环中等待,所以alex的事件如何进入事件循环,因为其语句在turtle.mainloop()之后运行跑?

1.What Does the .mainloop() really do? 1 .mainloop()的真正作用是什么?

Turtle's mainloop() calls tkinter's mainloop() which calls Tk's Tk_MainLoop() which is surprisingly simple: Turtle的mainloop()调用mainloop()mainloop() ,后者调用Tk的Tk_MainLoop() ,这非常简单:

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. 处理的事件包括键盘输入,按钮单击,窗口重塑,文件I / O,网络活动,计时器,显示刷新和任何其他已注册的回调。

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. 第15章的引言中可以找到关于mainloop的出色的一页描述。在Steve Lidie和Nancy Walsh撰写的O'Reily书籍Mastering Perl / Tk 中可以了解MainLoop Although it's a Perl/Tk book, the information regarding mainloop is valid for Python as well. 尽管这是一本Perl / Tk书,但有关mainloop的信息也适用于Python。 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? 2. .mainloop()是否一定总是在乌龟程序的末尾吗?

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. 大多数独立程序将包含它(或诸如.done().exitonclick() ),因为没有它的图形窗口将在完成时关闭。 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. 我在初学者乌龟程序中发现的一个常见错误是,在调用mainloop()之前创建了一个乌龟活动无限循环,然后想知道为什么不触发各种事件。

If you plan to have Tk process keyboard, mouse and timer events for you, then calling .mainloop() is how you get that started. 如果您打算让Tk处理键盘,鼠标和计时器事件,那么调用.mainloop()是开始的方式。 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. 在大多数Python / Tk程序中,这是最后一条语句,但是当所有Tk窗口都都关闭时,执行后还有其他代码。

We can think of turtle programming as writing plug-in code for Tk's main loop. 我们可以将乌龟编程看作是为Tk的主循环编写插件代码。 After we set things up, subsequent activity will be done by call back functions we've registered via on*() functions. 设置好之后,后续活动将通过我们通过on*()函数注册的回调函数完成。

3.I have used mainloop() before. 3.我以前用过mainloop()。 My question is, if I have the ffg code: ... Why does alex get an action event when the function yes() is run 我的问题是,如果我有ffg代码:...为什么在运行yes()函数时alex会得到一个动作事件

When your program runs, turtles Alex and Tess are piled atop each other in the center of the window. 当您的程序运行时,海龟Alex和Tess在窗口中心彼此堆叠。 When you click on this turtle stack, the event goes to Tess, who's both on top and has an event handler. 当您单击该Turtle Stack时,事件将发给Tess,Tess居于首位并具有事件处理程序。 In her event handler, Tess installs an event handler on Alex. 在她的事件处理程序中,Tess在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. 在Alex上安装事件处理程序的行为使Alex移到Tess的前面,上升到堆栈的顶部。 From now on, when you click on the turtle stack, Alex handles the events and they no longer reach Tess. 从现在开始,当您单击乌龟堆栈时,Alex处理事件,事件不再到达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. 您可以将Alex和Tess移到窗口中的不同位置,然后单击它们以确认Alex直到第一次单击Tess才开始接收事件。

So mainloop() is an infinite loop that basically blocks the execution of your code at a certain point. 所以mainloop()是一个无限循环,基本上在某个点上阻止了代码的执行。 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. 您将永远不会看到输出和打印语句,因为没有循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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