Python海龟等待单击

Python海龟等待单击,python,events,recursion,turtle-graphics,Python,Events,Recursion,Turtle Graphics,我希望能够暂停并思考此程序的每一步,然后通过单击屏幕进入下一步。起初,我尝试添加一系列事件,但后来我的大脑开始提醒我,这不是一个程序性程序,第一个绑定仍然是唯一的一个(!)。主程序如下,非常感谢任何帮助 def tree(self, branchLen): if branchLen > 5: self.screen.onscreenclick(lambda x,y: self.t.forward(branchLen)) self.screen.onscr

我希望能够暂停并思考此程序的每一步,然后通过单击屏幕进入下一步。起初,我尝试添加一系列事件,但后来我的大脑开始提醒我,这不是一个程序性程序,第一个绑定仍然是唯一的一个(!)。主程序如下,非常感谢任何帮助

  def tree(self, branchLen):
    if branchLen > 5:
      self.screen.onscreenclick(lambda x,y: self.t.forward(branchLen))
      self.screen.onscreenclick(lambda x,y: self.t.right(20))
      self.tree(branchLen-15)
      self.screen.onscreenclick(lambda x,y: self.t.left(40))
      self.tree(branchLen-15)
      self.screen.onscreenclick(lambda x,y: self.t.right(20))
      self.screen.onscreenclick(lambda x,y: self.t.backward(branchLen))


救命吧!我们将Turtle子类化,使之成为一个将所有要求它做的事情排队的类。然后我们设置一个
onclick()
处理程序,从队列中弹出一个项目并执行它:

import sys
import turtle

class QueuedTurtle(turtle.RawTurtle):

    _queue = []
    _pen = None
    _screen = None

    def __init__(self, shape=turtle._CFG["shape"], undobuffersize=turtle._CFG["undobuffersize"], visible=turtle._CFG["visible"]):

        if QueuedTurtle._screen is None:
            QueuedTurtle._screen = turtle.Screen()

        self._screen.onclick(lambda *args: self.queue_pop())

        turtle.RawTurtle.__init__(self, QueuedTurtle._screen, shape=shape, undobuffersize=undobuffersize, visible=visible)

    def queue_pop(self):
        if self._queue:
            function, arguments = self._queue.pop(0)
            return function(*arguments)

        print("Empty queue popped!", file=sys.stderr)

    def backward(self, *args):
        self._queue.append((super().backward, args))

    def forward(self, *args):
        self._queue.append((super().forward, args))

    def right(self, *args):
        self._queue.append((super().right, args))

    def left(self, *args):
        self._queue.append((super().left, args))

    def up(self, *args):
        self._queue.append((super().up, args))

    def down(self, *args):
        self._queue.append((super().down, args))

    def color(self, *args):
        self._queue.append((super().color, args))


class Tree(object):
    def __init__(self):
        self.t = QueuedTurtle()

        self.t.left(90)
        self.t.up()
        self.t.backward(100)
        self.t.down()
        self.t.color("green")
        self.tree(75)

    def tree(self, branchLen):
        if branchLen > 5:
            self.t.forward(branchLen)
            self.t.right(20)
            self.tree(branchLen - 15)
            self.t.left(40)
            self.tree(branchLen - 15)
            self.t.right(20)
            self.t.backward(branchLen)

tree = Tree()

tree.tree(10)

turtle.mainloop()
这是一个部分实现,其代码仅足以使示例程序正常工作。运行它,然后开始单击鼠标


我们甚至可以通过编程方式为QueuedTurtle生成包装器方法。

用面向对象的方法来拯救怎么样!我们将Turtle子类化,使之成为一个将所有要求它做的事情排队的类。然后我们设置一个
onclick()
处理程序,从队列中弹出一个项目并执行它:

import sys
import turtle

class QueuedTurtle(turtle.RawTurtle):

    _queue = []
    _pen = None
    _screen = None

    def __init__(self, shape=turtle._CFG["shape"], undobuffersize=turtle._CFG["undobuffersize"], visible=turtle._CFG["visible"]):

        if QueuedTurtle._screen is None:
            QueuedTurtle._screen = turtle.Screen()

        self._screen.onclick(lambda *args: self.queue_pop())

        turtle.RawTurtle.__init__(self, QueuedTurtle._screen, shape=shape, undobuffersize=undobuffersize, visible=visible)

    def queue_pop(self):
        if self._queue:
            function, arguments = self._queue.pop(0)
            return function(*arguments)

        print("Empty queue popped!", file=sys.stderr)

    def backward(self, *args):
        self._queue.append((super().backward, args))

    def forward(self, *args):
        self._queue.append((super().forward, args))

    def right(self, *args):
        self._queue.append((super().right, args))

    def left(self, *args):
        self._queue.append((super().left, args))

    def up(self, *args):
        self._queue.append((super().up, args))

    def down(self, *args):
        self._queue.append((super().down, args))

    def color(self, *args):
        self._queue.append((super().color, args))


class Tree(object):
    def __init__(self):
        self.t = QueuedTurtle()

        self.t.left(90)
        self.t.up()
        self.t.backward(100)
        self.t.down()
        self.t.color("green")
        self.tree(75)

    def tree(self, branchLen):
        if branchLen > 5:
            self.t.forward(branchLen)
            self.t.right(20)
            self.tree(branchLen - 15)
            self.t.left(40)
            self.tree(branchLen - 15)
            self.t.right(20)
            self.t.backward(branchLen)

tree = Tree()

tree.tree(10)

turtle.mainloop()
这是一个部分实现,其代码仅足以使示例程序正常工作。运行它,然后开始单击鼠标


我们甚至可以通过编程方式为QueuedTurtle生成包装器方法。

效果很好-谢谢。请注意,理解QueuedTurtle类对我来说需要一些认真的研究。我将从修改队列开始,但任何关于如何工作的进一步信息都会有所帮助。例如,
\u CFG
指的是什么?@Robin,
\u init\u
方法的大部分是从Turtle类复制的,Turtle类也是RawTurtle的子类——我尝试过对Turtle进行子类化,但效果更好。此方法的唯一补充是
onclick
处理程序的设置。
\u CFG
东西从某种配置结构中获取信息并初始化turtle,除了模拟turtle之外,对QueuedTurtle的功能没有任何影响。这很好-谢谢。请注意,理解QueuedTurtle类对我来说需要一些认真的研究。我将从修改队列开始,但任何关于如何工作的进一步信息都会有所帮助。例如,
\u CFG
指的是什么?@Robin,
\u init\u
方法的大部分是从Turtle类复制的,Turtle类也是RawTurtle的子类——我尝试过对Turtle进行子类化,但效果更好。此方法的唯一补充是
onclick
处理程序的设置。
\u CFG
东西从某种配置结构中获取信息并初始化turtle,与QueuedTurtle的功能无关,只是它模拟了一个turtle。