海龟图形Python,.mainloop()

问题描述 投票:0回答:2

我正在用 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()
(第一只海龟)会收到动作事件?我知道它确实如此,因为该函数被调用了,但实际上发生了什么?我的意思是语句
turtle.mainloop()
在 tess 被点击之前运行,并且 tess 的动作事件在事件循环中等待,那么 alex 的事件如何进入事件循环,因为它的语句是在
turtle.mainloop()
运行之后运行的?

python user-interface events turtle-graphics event-loop
2个回答
4
投票

1..mainloop() 的作用是什么?

Turtle 的

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

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

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

对主循环的精彩一页描述可以在 Steve Lidie 和 Nancy Walsh 所著的 O'Reily 书 Mastering Perl/Tk 中的 Chapter 15. Anatomy of the MainLoop 中找到。 尽管这是一本 Perl/Tk 书籍,但有关 mainloop 的信息也适用于 Python。 您可以在线找到此材料,但我不会在此处添加链接,因为我不知道哪些在线副本(如果有)是合法发布的。 但您有足够的信息来搜索它。

2..mainloop() 是否必须始终位于海龟程序的末尾?

不。 它应该是精心设计的程序的一部分,但不是必需的。 大多数独立程序都会包含它(或者像

.done()
.exitonclick()
这样的名称),因为如果没有它,图形窗口将在完成时关闭。 但有些情况,例如。也许空闲,不需要它来保持图形可见。 我在初学者的海龟程序中发现的一个常见错误是在调用
mainloop()
之前创建海龟活动的无限循环,然后想知道为什么各种事件不触发。

如果您计划让 Tk 为您处理键盘、鼠标和计时器事件,那么调用

.mainloop()
就是您开始的方式。 在大多数 Python/Tk 程序中,它是最后一条语句,但它后面可能还有其他代码,当所有 Tk 窗口全部关闭时执行。

我们可以将海龟编程视为为 Tk 的主循环编写插件代码。 设置完成后,后续活动将通过我们通过

on*()
函数注册的回调函数来完成。

3.我以前用过mainloop()。我的问题是,如果我有 f.f.g 代码: ... 为什么 alex 在函数执行时会得到一个动作事件 yes() 已运行

当你的程序运行时,海龟 Alex 和 Tess 在窗口中央相互堆叠。 当您单击此海龟堆栈时,事件将发送给 Tess,她位于顶部并且有一个事件处理程序。 在她的事件处理程序中,Tess 在 Alex 上安装了一个事件处理程序。在 Alex 上安装事件处理程序的行为会导致 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
投票

所以 mainloop() 是一个无限循环,基本上会在某个点阻止代码的执行。您调用它一次(并且仅调用一次)。

所以可以说:

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

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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.