Python Turtle Wait for Click

拟墨画扇 提交于 2019-12-12 04:24:56

问题


I'd like to be able to pause and contemplate each step of this program, and move on to the next step by clicking the screen. Initially I tried adding a bunch of events, but then my brain kicked in and reminded me that this is not a procedural program and the first binding would remain the only one(!). Main program below, any help much appreciated.

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

import turtle

class Tree(object):
  def __init__(self):
    self.t = turtle.Turtle()
    self.screen = turtle.Screen()

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

回答1:


How about OOP to the rescue! We subclass Turtle to make one that queues everything it's asked to do. Then we set an onclick() handler that pops one item off that queue and executes it:

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

This is a partial implementation with just enough code to make your example program work. Run it, and then start clicking your mouse.

We can probably even programmatically generate the wrapper methods for QueuedTurtle.



来源:https://stackoverflow.com/questions/39697634/python-turtle-wait-for-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!