mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-126349: Add 'fill', 'poly', and 'no_animation' context managers to turtle (#126350)
Co-authored-by: Marie Roald <roald.marie@gmail.com> Co-authored-by: Yngve Mardal Moe <yngve.m.moe@gmail.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Daniel Hollas <danekhollas@gmail.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Erlend E. Aasland <erlend@python.org>
This commit is contained in:
parent
4dade055f4
commit
d3adf02c90
5 changed files with 277 additions and 16 deletions
|
@ -107,6 +107,7 @@ import sys
|
|||
|
||||
from os.path import isfile, split, join
|
||||
from pathlib import Path
|
||||
from contextlib import contextmanager
|
||||
from copy import deepcopy
|
||||
from tkinter import simpledialog
|
||||
|
||||
|
@ -114,23 +115,24 @@ _tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
|
|||
'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
|
||||
_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
|
||||
'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
|
||||
'getshapes', 'listen', 'mainloop', 'mode', 'numinput',
|
||||
'getshapes', 'listen', 'mainloop', 'mode', 'no_animation', 'numinput',
|
||||
'onkey', 'onkeypress', 'onkeyrelease', 'onscreenclick', 'ontimer',
|
||||
'register_shape', 'resetscreen', 'screensize', 'save', 'setup',
|
||||
'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update',
|
||||
'window_height', 'window_width']
|
||||
'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles',
|
||||
'update', 'window_height', 'window_width']
|
||||
_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
|
||||
'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
|
||||
'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
|
||||
'fillcolor', 'filling', 'forward', 'get_poly', 'getpen', 'getscreen', 'get_shapepoly',
|
||||
'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
|
||||
'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
|
||||
'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
|
||||
'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
|
||||
'seth', 'setheading', 'setpos', 'setposition',
|
||||
'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle',
|
||||
'speed', 'st', 'stamp', 'teleport', 'tilt', 'tiltangle', 'towards',
|
||||
'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
|
||||
'fillcolor', 'fill', 'filling', 'forward', 'get_poly', 'getpen',
|
||||
'getscreen', 'get_shapepoly', 'getturtle', 'goto', 'heading',
|
||||
'hideturtle', 'home', 'ht', 'isdown', 'isvisible', 'left', 'lt',
|
||||
'onclick', 'ondrag', 'onrelease', 'pd', 'pen', 'pencolor', 'pendown',
|
||||
'pensize', 'penup', 'poly', 'pos', 'position', 'pu', 'radians', 'right',
|
||||
'reset', 'resizemode', 'rt', 'seth', 'setheading', 'setpos',
|
||||
'setposition', 'setundobuffer', 'setx', 'sety', 'shape', 'shapesize',
|
||||
'shapetransform', 'shearfactor', 'showturtle', 'speed', 'st', 'stamp',
|
||||
'teleport', 'tilt', 'tiltangle', 'towards', 'turtlesize', 'undo',
|
||||
'undobufferentries', 'up', 'width',
|
||||
'write', 'xcor', 'ycor']
|
||||
_tg_utilities = ['write_docstringdict', 'done']
|
||||
|
||||
|
@ -1275,6 +1277,26 @@ class TurtleScreen(TurtleScreenBase):
|
|||
return self._delayvalue
|
||||
self._delayvalue = int(delay)
|
||||
|
||||
@contextmanager
|
||||
def no_animation(self):
|
||||
"""Temporarily turn off auto-updating the screen.
|
||||
|
||||
This is useful for drawing complex shapes where even the fastest setting
|
||||
is too slow. Once this context manager is exited, the drawing will
|
||||
be displayed.
|
||||
|
||||
Example (for a TurtleScreen instance named screen
|
||||
and a Turtle instance named turtle):
|
||||
>>> with screen.no_animation():
|
||||
... turtle.circle(50)
|
||||
"""
|
||||
tracer = self.tracer()
|
||||
try:
|
||||
self.tracer(0)
|
||||
yield
|
||||
finally:
|
||||
self.tracer(tracer)
|
||||
|
||||
def _incrementudc(self):
|
||||
"""Increment update counter."""
|
||||
if not TurtleScreen._RUNNING:
|
||||
|
@ -3380,6 +3402,24 @@ class RawTurtle(TPen, TNavigator):
|
|||
"""
|
||||
return isinstance(self._fillpath, list)
|
||||
|
||||
@contextmanager
|
||||
def fill(self):
|
||||
"""A context manager for filling a shape.
|
||||
|
||||
Implicitly ensures the code block is wrapped with
|
||||
begin_fill() and end_fill().
|
||||
|
||||
Example (for a Turtle instance named turtle):
|
||||
>>> turtle.color("black", "red")
|
||||
>>> with turtle.fill():
|
||||
... turtle.circle(60)
|
||||
"""
|
||||
self.begin_fill()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
self.end_fill()
|
||||
|
||||
def begin_fill(self):
|
||||
"""Called just before drawing a shape to be filled.
|
||||
|
||||
|
@ -3400,7 +3440,6 @@ class RawTurtle(TPen, TNavigator):
|
|||
self.undobuffer.push(("beginfill", self._fillitem))
|
||||
self._update()
|
||||
|
||||
|
||||
def end_fill(self):
|
||||
"""Fill the shape drawn after the call begin_fill().
|
||||
|
||||
|
@ -3504,6 +3543,27 @@ class RawTurtle(TPen, TNavigator):
|
|||
if self.undobuffer:
|
||||
self.undobuffer.cumulate = False
|
||||
|
||||
@contextmanager
|
||||
def poly(self):
|
||||
"""A context manager for recording the vertices of a polygon.
|
||||
|
||||
Implicitly ensures that the code block is wrapped with
|
||||
begin_poly() and end_poly()
|
||||
|
||||
Example (for a Turtle instance named turtle) where we create a
|
||||
triangle as the polygon and move the turtle 100 steps forward:
|
||||
>>> with turtle.poly():
|
||||
... for side in range(3)
|
||||
... turtle.forward(50)
|
||||
... turtle.right(60)
|
||||
>>> turtle.forward(100)
|
||||
"""
|
||||
self.begin_poly()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
self.end_poly()
|
||||
|
||||
def begin_poly(self):
|
||||
"""Start recording the vertices of a polygon.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue