首页 > 解决方案 > 海龟图形:如何实现暂停功能?

问题描述

我正在尝试使用 python 3 乌龟图形来做演示软件之类的事情:画一些东西,暂停击键以便演示者可以解释,然后画下一个东西。

这是我尝试过的一种解决方案(不起作用):

import turtle
import time

paused = False

def unpause():
    print("unpause() called")
    global paused
    paused = False

def pause():
    global paused
    paused = True
    while paused:
        time.sleep(0.1)


t = turtle.Turtle()

# set up listener
t.screen.listen()
t.screen.onkeypress(unpause)

# draw something
t.hideturtle()
t.pensize(5)
t.speed(1)
t.pu()
t.goto(-300,-300)
t.pd()
t.goto(-300, 300)

# pause until key is pressed
pause()

# draw some more
t.pu()
t.goto(300,-300)
t.pd()
t.goto(300, 300)

t.screen.mainloop()

问题是睡眠调用循环完全阻止了按键被检测到,即使我使用了一个非常短(100 毫秒)睡眠的 while 循环。

如果我在绘制第一行时按了一个键,我会在控制台中看到“unpause() called”,因此我知道键绑定处于活动状态。

为什么没有检测到按键?我不知道内部原理,但我认为击键会记录在某个缓冲区中,并且在睡眠调用之间的休息期间,侦听器将读取缓冲区并取消设置paused全局变量。这没有发生。

还有其他方法可以实现吗?

这是在 Debian Linux 系统上。

标签: pythonpython-3.xturtle-graphicspython-turtle

解决方案


采纳您的建议给我的想法(感谢 martineau 和 kederrac!)我能够想出一个解决方案。它涉及将我的每个绘图任务包装在一个函数中,然后使用一个调度函数,该函数要么等待带有ontimer循环的按键,要么调用下一个绘图函数。

这个概念验证代码完全使用了太多的全局变量,但它展示了这种技术:

import turtle

t = turtle.Turtle()
paused = False
current_task = 0

def unpause():
    global paused
    paused = False

def turtle_setup():
    global t
    t.screen.onkeypress(unpause)
    t.screen.listen()
    t.hideturtle()
    t.pensize(5)
    t.speed(1)

def draw_task_finished():
    global paused, current_task, drawing_tasks
    current_task += 1
    paused = True
    if current_task < len(drawing_tasks):
        draw_task_after_keypress()

def draw_task_after_keypress():
    global paused, current_task
    if paused:
        turtle.ontimer(draw_task_after_keypress, 100)
    else:
        drawing_tasks[current_task]()

def draw_thing_one():
    global t
    t.pu()
    t.goto(-300,-300)
    t.pd()
    t.goto(-300, 300)
    draw_task_finished()

def draw_thing_two():
    global t
    t.pu()
    t.goto(300,-300)
    t.pd()
    t.goto(300, 300)
    draw_task_finished()

drawing_tasks = [draw_thing_one, draw_thing_two]

turtle_setup()
drawing_tasks[0]()

t.screen.mainloop()

推荐阅读