问题
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