Turtle Graphics Python,.mainloop()

时间:2016-09-10 18:22:57

标签: python user-interface events turtle-graphics event-loop

我正在用Python编程,我有几个问题,我无法在任何地方找到答案(请阅读所有问题,因为它们构建到我的上一个问题):

1. .mainloop()真的有什么作用?我在Stack Overflow中阅读了所有答案,我还检查了文档说明。

2. .mainloop()总是必须在海龟计划的最后?

3.我之前使用过.mainloop()。我的问题是,如果我有f.f.g代码:

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()

为什么alex在运行函数yes()时会获得一个动作事件?我知道这样做是因为调用了函数,但实际发生了什么?我的意思是在单击tess之前运行语句turtle.mainloop(),并且在事件循环中等待tess的动作事件,所以alex的事件如何在事件循环中进入,因为它的语句是在turtle.mainloop()运行后运行?

2 个答案:

答案 0 :(得分:2)

  

1..mainloop()真的有什么作用?

Turtle的mainloop()调用tkinter mainloop()调用Tk的Tk_MainLoop(),这非常简单:

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

当有任何主窗口打开时,它会在无限循环中一次处理一个事件。处理的事件包括键盘输入,按钮单击,窗口重塑,文件I / O,网络活动,计时器,显示刷新和任何其他已注册的回调。

主要浏览器中的 第15章主界面剖析 的介绍中可以找到一个优秀的,一页的mainloop描述 由Steve Lidie和Nancy Walsh掌握Perl / Tk 。虽然它是一本Perl / Tk书,但有关mainloop的信息也适用于Python。您可以在线查找此资料,但我不会在此处添加链接,因为我不知道哪些在线副本是合法发布的。但是你有足够的信息来搜索它。

  

2. .mainloop()总是必须在海龟计划的最后?

没有。它应该是精心设计的程序的一部分,但不是必需的。大多数独立程序都会包含它(或称之为.done().exitonclick()的东西),因为图形窗口在没有它的情况下将在完成时关闭。但有些情况,例如。 IDLE也许,不需要它来保持图形可见。我在初学者的乌龟程序中发现的一个常见错误是在调用mainloop()之前创建一个无限循环的海龟活动,然后想知道为什么不会发生各种事件。

如果您打算让Tk处理键盘,鼠标和计时器事件,那么调用.mainloop()就是如何开始的。在大多数Python / Tk程序中,它是最后一个语句,但是当所有Tk窗口全部关闭时,可以执行其他代码。

我们可以将乌龟编程视为编写Tk主循环的插件代码。在我们进行了设置后,后续活动将通过我们通过on*()函数注册的回调函数完成。

  

3.之前我使用过mainloop()。我的问题是,如果我有f.f.g代码:...为什么alex在函数时获得动作事件   是()运行

当你的程序运行时,海龟Alex和Tess在窗口中央堆叠在一起。当你点击这个乌龟堆栈时,事件会发送给Tess,Tess既是顶级的又有一个事件处理程序。在她的事件处理程序中,Tess在Alex上安装了一个事件处理程序。在Alex上安装事件处理程序的行为导致Alex在Tess前面移动,上升到堆栈的顶部。从现在开始,当你点击龟堆时,Alex处理事件并且他们不再到达Tess。如果我们给它们不同的颜色和不同的事件处理程序,我们可以清楚地看到这一点:

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()

点击龟堆会产生:

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

您可以将Alex和Tess移动到窗口中的不同位置,然后单击它们以确认Alex在第一次点击Tess之前没有开始接收事件。

答案 1 :(得分:0)

所以mainloop()是一个无限循环,它基本上阻止了代码在某一点的执行。你叫它一次(只有一次)。

所以我们说:

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

你永远不会看到输出和打印语句,因为没有循环。