一、概述
在 Python 中,海龟绘图提供了一个实体“海龟”形象(带有画笔的小机器动物),假定它在地板上平铺的纸张上画线。
二、运行环境
本文运行环境:Windows11,Python3.11,Pycharm2023.1.4
使用之前,需要先导入 turtle 模块的所有对象:
from turtle import *
或
import turtle as t
建议使用第二种,如果你遇到了 No module named '_tkinter'
错误,则需要在你的系统中安装 Tk
接口包。
三、RawTurtle/Turtle 方法和对应函数
Turtle
是RawTurtle
的子类。
3.1 海龟动作
3.1.1移动和绘制
作用 | 方法名称 | 简写 | 参数 | 描述 |
---|---|---|---|---|
前进 | forward(distance) | fd(distance) | distance 一个数值 (整型或浮点型) | 海龟前进distance 指定的距离,方向为海龟的朝向。 |
后退 | backward(distance) | bk(distance) back(distance) | distance 一个数值 (整型或浮点型) | 海龟后退distance 指定的距离,方向与海龟的朝向相反。不改变海龟的朝向。 |
右转 | right(angle) | rt(angle) | angle 一个数值 (整型或浮点型) | 海龟右转angle 个单位。(单位默认为角度,但可通过degrees() 和radians() 函数改变设置。) 角度的正负由海龟模式确定,参见mode() 。 |
左转 | left(angle) | lt(angle) | angle 一个数值 (整型或浮点型) | 海龟左转angle 个单位。(单位默认为角度,但可通过degrees() 和radians() 函数改变设置。) 角度的正负由海龟模式确定,参见mode() 。 |
前往/定位 | goto(x, y=None) | setpos(x, y=None) setposition(x, y=None) | x 一个数值或数值对/向量y 一个数值或None 如果 y 为 None,x 应为一个表示坐标的数值对或Vec2D 类对象 (例如pos() 返回的对象) | 海龟移动到一个绝对坐标。如果画笔已落下将会画线。不改变海龟的朝向。 |
前往/定位 | teleport(x, y=None, *, fill_gap=False) | —— | x 一个数值或None y 一个数值或None fill_gap 布尔值 | 将海龟移到某个绝对位置。 不同于goto(x, y) ,这将不会画一条线段。 海龟的方向不变。 如果当前正在填充,离开后原位置上的多边形将被填充,在移位后将再次开始填充。 这可以通过fill_gap=True 来禁用,此设置将使在移位期间海龟的移动轨迹线像在goto(x, y) 中一样被当作填充边缘。 |
设置x 坐标 | setx(x) | —— | x 一个数值 (整型或浮点型) | 设置海龟的横坐标为x ,纵坐标保持不变。 |
设置y 坐标 | sety(y) | —— | y 一个数值 (整型或浮点型) | 设置海龟的纵坐标为y ,横坐标保持不变。 |
设置朝向 | setheading(to_angle) | seth(to_angle) | to_angle 一个数值 (整型或浮点型) | 设置海龟的朝向为to_angle 。以下是以角度表示的几个常用方向:标准模式:0-东,90-北,180-西,270-南。 logo模式:0-北,90-东,180-南,270-西。 |
返回原点 | home() | —— | —— | 海龟移至初始坐标 (0,0) ,并设置朝向为初始方向 (由海龟模式确定,参见 mode() )。 |
画圆 | circle(radius, extent=None, steps=None) | —— | radius 一个数值extent 一个数值 (或None )steps 一个整型数 (或None ) | 绘制一个radius 指定半径的圆。圆心在海龟左边radius 个单位;extent 为一个夹角,用来决定绘制圆的一部分。如未指定extent 则绘制整个圆。如果 extent 不是完整圆周,则以当前画笔位置为一个端点绘制圆弧。如果radius 为正值则朝逆时针方向绘制圆弧,否则朝顺时针方向。最终海龟的朝向会依据extent 的值而改变。圆实际是以其内切正多边形来近似表示的,其边的数量由steps 指定。如果未指定边数则会自动确定。此方法也可用来绘制正多边形。 |
画点 | dot(size=None, *color) | —— | size 一个整型数 >= 1 (如果指定)color 一个颜色字符串或颜色数值元组 | 绘制一个直径为size ,颜色为color 的圆点。如果size 未指定,则直径取pensize+4 和2*pensize 中的较大值。 |
印章 | stamp() | —— | —— | 在海龟当前位置印制一个海龟形状。返回该印章的stamp_id ,印章可以通过调用clearstamp(stamp_id) 来删除。 |
清除印章 | clearstamp(stampid) | —— | stampid 一个整型数,必须是之前stamp() 调用的返回值 | 删除stampid 指定的印章。 |
清除多个印章 | clearstamps(n=None) | —— | n 一个整型数 (或None ) | 删除全部或前/后n 个海龟印章。如果n 为None 则删除全部印章,如果n > 0 则删除前n 个印章,否则如果 n < 0 则删除后n 个印章。 |
撤消 | undo() | —— | —— | 撤消 (或连续撤消) 最近的一个 (或多个) 海龟动作。可撤消的次数由撤消缓冲区的大小决定。 |
速度 | speed(speed=None) | —— | speed 一个0..10 范围内的整型数或速度字符串。 | 设置海龟移动的速度为0..10 表示的整型数值。如未指定参数则返回当前速度。如果输入数值大于10 或小于0.5 则速度设为0 。速度字符串与速度值的对应关系如下:"fastes" :0 —— 最快"fast" :10 ——快"normal" : 6 —— 正常"slow" :3 ——慢"slowest" :1 ——最慢注意: speed = 0 表示没有动画效果。forward/back 将使海龟向前/向后跳跃,同样的left/right 将使海龟立即改变朝向。 |
from turtle import *# 利用前进后退左右转画一个正方形
fd(100) # 前进100
rt(90) # 右转90度
bk(100) # 后退100
rt(90) # 右转90度
fd(100) # 前进100
lt(90) # 左转90度
fd(100) # 前进100# 在正方形的左边画一个圆
teleport(-200, 200) # 将画笔移动至坐标点(-200,200)位置,不会画线。
circle(100) # 逆时针画一个半径100的圆
goto(-200, 0) # 将画笔移动至坐标(-200,0)位置,会画出一条线。
circle(-100, 360, 6) # 顺时针画一个六变形
teleport(-300, 0) # 画笔移动至六边形形心
dot(5, 'red') # 利用红色点画出六边形形心
st = stamp() # 设置一个印章
speed('slowest') # 将画笔速度调至最慢
home() # 画笔返回原点
clearstamp(st) # 删除设置的印章
done() # 完成后不关闭绘图窗口
3.1.2获取海龟的状态
作用 | 方法名称 | 简写 | 参数 | 详细描述 |
---|---|---|---|---|
获取位置 | position() | pos() | —— | 返回海龟当前的坐标(x,y) (为Vec2D 矢量类对象)。 |
目标方向 | towards(x, y=None) | —— | x 一个数值或数值对/矢量,或一个海龟实例y 一个数值——如果x 是一个数值,否则为None | 返回从海龟位置到由 (x,y) 、矢量或另一海龟所确定位置的连线的夹角。 此数值依赖于海龟的初始朝向,这又取决于"standard"/"world" 或"logo" 模式设置。 |
x 坐标 | xcor() | —— | —— | 返回海龟的x 坐标。 |
y 坐标 | ycor() | —— | —— | 返回海龟的y 坐标。 |
朝向 | heading() | —— | —— | 返回海龟当前的朝向 (数值依赖于海龟模式参见mode() )。 |
距离 | distance(x, y=None) | —— | x 一个数值或数值对/矢量,或一个海龟实例y 一个数值——如果 x 是一个数值,否则为None | 返回从海龟位置到由(x,y) ,矢量或另一海龟对应位置的单位距离。 |
from turtle import *fd(100)
pos = position()
print(pos) # 结果:(100.00,0.00)
to = towards(100, 100)
print(to) # 结果:90.0
x = xcor()
print(x) # 结果:100.0
y = ycor()
print(y) # 结果:0.0
lt(90)
heading = heading()
print(heading) # 结果:90.0
s = distance(100, 100)
print(s) # 结果:100.0
done() # 完成后不关闭绘图窗口
3.1.3设置与度量单位
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
角度 | degrees(fullcircle=360.0) | fullcircle 一个数值 | 设置角度的度量单位,即设置一个圆周为多少 “度”。默认值为 360 度。 |
弧度 | radians() | —— | 设置角度的度量单位为弧度。其值等于degrees(2*math.pi) 。 |
3.2画笔控制
3.2.1绘图状态
作用 | 方法名称 | 简写 | 参数 | 详细描述 |
---|---|---|---|---|
画笔落下 | pendown() | pd() down() | —— | 画笔落下 – 移动时将画线。 |
画笔抬起 | penup() | pu() up() | —— | 画笔抬起 – 移动时不画线。 |
画笔粗细 | pensize(width=None) | width(width=None) | width 一个正数值 | 设置线条的粗细为width 或返回该值。如果resizemode 设为"auto" 并且turtleshape 为多边形,该多边形也以同样组细的线条绘制。如未指定参数,则返回当前的pensize 。 |
画笔 | pen(pen=None, **pendict) | —— | pen 一个包含部分或全部下列键的字典。pendict 一个或多个以下列键为关键字的关键字参数。返回或设置画笔的属性,以一个包含以下键值对的 “画笔字典” 表示:"shown": True/False "pendown": True/False "pencolor": 颜色字符串或颜色元组 "fillcolor": 颜色字符串或颜色元组 "pensize": 正数值 "speed": 0..10 范围内的数值 "resizemode": "auto" 或 "user" 或 "noresize" "stretchfactor": (正数值, 正数值) "outline": 正数值 "tilt": 数值 | 此字典可作为后续调用pen() 时的参数,以恢复之前的画笔状态。另外还可将这些属性作为关键词参数提交。使用此方式可以用一条语句设置画笔的多个属性。 |
画笔是否落下 | isdown() | —— | —— | 如果画笔落下返回True ,如果画笔抬起返回False 。 |
from turtle import *goto(100, 0)
penup()
print(isdown()) # 结果:False
goto(200, 0)
pendown()
print(isdown()) # 结果:True
pensize(5)
pen(pencolor='red', speed=1) # 设置画笔颜色为红色,速度为1。
goto(300, 0)
done() # 结束不关闭绘制窗口
3.2.2颜色控制
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
颜色 | color(*args) | 允许多种输入格式。使用如下0 至3 个参数:color() 返回以一对颜色描述字符串或元组表示的当前画笔颜色和填充颜色,两者可分别由 pencolor() 和fillcolor() 返回。color(colorstring), color((r,g,b)), color(r,g,b) 输入格式与pencolor() 相同,同时设置填充颜色和画笔颜色为指定的值。color(colorstring1, colorstring2), color((r1,g1,b1), (r2,g2,b2)) 相当于pencolor(colorstring1) 加fillcolor(colorstring2) ,使用其他输入格式的方法也与之类似。 | 返回或设置画笔颜色和填充颜色。如果turtleshape 为多边形,该多边形轮廓与填充也使用新设置的颜色。 |
画笔颜色 | pencolor() | 允许以下四种输入格式:: (1) pencolor() 返回以颜色描述字符串或元组 (见示例) 表示的当前画笔颜色。可用作其他color/pencolor/fillcolor 调用的输入。(2) pencolor(colorstring) 设置画笔颜色为colorstring 定的Tk 颜色描述字符串,例如"red" 、"yellow" 或"#33cc8c" 。(3) pencolor((r, g, b)) 设置画笔颜色为以r, g, b 元组表示的RGB 颜色。r, g, b 的取值范围应为0..colormode ,colormode 的值为1.0 或255 (参见colormode() )。(4) pencolor(r, g, b) 设置画笔颜色为以r, g, b 表示的RGB 颜色。r, g, b 的取值范围应为0..colormode 。 | 返回或设置画笔颜色。如果 turtleshape 为多边形,该多边形轮廓也以新设置的画笔颜色绘制。 |
填充颜色 | fillcolor() | 允许以下四种输入格式: (1) fillcolor() 返回以颜色描述字符串或元组 (见示例) 表示的当前填充颜色。可用作其他color/pencolor/fillcolor 调用的输入。(2) fillcolor(colorstring) 设置填充颜色为colorstring 指定的Tk 颜色描述字符串,例如"red" 、"yellow" 或"#33cc8c" 。(3) fillcolor((r, g, b)) 设置填充颜色为以 r, g, b 元组表示的RGB 颜色。r, g, b 的取值范围应为0..colormode ,colormode 的值为1.0 或255 (参见colormode() )。(4)fillcolor(r, g, b)设置填充颜色为 r, g, b 表示的RGB 颜色。r, g, b 的取值范围应为0..colormode 。 | 返回或设置填充颜色。如果turtleshape 为多边形,该多边形内部也以新设置的填充颜色填充。 |
3.2.3填充
作用 | 方法名称 | 详细描述 |
---|---|---|
是否填充 | filling() | 返回填充状态 (填充为True ,否则为False )。 |
开始填充 | begin_fill() | 在绘制要填充的形状之前调用。 |
结束填充 | end_fill() | 填充上次调用begin_fill() 之后绘制的形状。 |
from turtle import *color('red', 'blue') # 设置画笔颜色:红色,填充颜色:蓝色
begin_fill() # 开始填充
circle(100)
end_fill() # 结束填充
teleport(200, 0) # 移动画笔至(200,0)位置
pencolor('green') # 设置画笔颜色:绿色
fillcolor('yellow') # 设置填充颜色:黄色
begin_fill()
circle(100, 360, 5) # 画一个正五边形
end_fill()
done() # 绘制结束不关闭绘图窗口
3.2.4更多绘图控制
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
重置 | reset() | —— | 从屏幕中删除海龟的绘图,海龟回到原点并设置所有变量为默认值。 |
清空 | clear() | —— | 从屏幕中删除指定海龟的绘图。不移动海龟。海龟的状态和位置以及其他海龟的绘图不受影响。 |
书写 | write(arg, move=False, align='left', font=('Arial', 8, 'normal')) | arg 要书写到TurtleScreen 的对象move ——True/False align ——字符串"left" , "center" 或"right" 。font ——一个三元组 (fontname, fontsize, fonttype) 。 | 基于align ("left", "center" 或 "right") 并使用给定的字体将文本 ——arg 的字符串表示形式 —— 写到当前海龟位置。 如果move 为真值,画笔会移至文本的右下角。 默认情况下move 为False 。 |
from turtle import *# 利用循环绘制一个正方形
pencolor('green')
for s in range(4):fd(100)lt(90)
teleport(200, 200)
circle(100)
reset() # 删除绘图并重置画笔
# 利用循环绘制一个五角星
goto(200, 0)
pencolor('red')
write('五角星', True, "center", ('Arial', 8, 'normal')) # 设置书写字体内容,位置,类型,大小,风格
for m in range(5):fd(100)rt(144)
clear() # 清空不重置画笔
home() # 可以看到画笔颜色没有改变
done()
3.3海龟状态
3.3.1可见性
作用 | 方法名称 | 简写 | 详细描述 |
---|---|---|---|
显示海龟 | showturtle() | st() | 使海龟可见。 |
隐藏海龟 | hideturtle() | ht() | 使海龟不可见。当你绘制复杂图形时这是个好主意,因为隐藏海龟可显著加快绘制速度。 |
是否可见 | isvisible() | —— | 如果海龟显示返回True ,如果海龟隐藏返回False 。 |
3.3.2外观
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
形状 | shape(name=None) | name 一个有效的形状名字符串。 | 设置海龟形状为name 指定的形状名,如未指定形状名则返回当前的形状名。ame 指定的形状名应存在于TurtleScreen 的shape 字典中。多边形的形状初始时有以下几种:"arrow" ,"turtle" , "circle" ,"square" ,"triangle" ,"classic" 。要了解如何处理形状请参看Screen 方法register_shape() 。 |
大小调整模式 | resizemode(rmode=None) | rmode 字符串"auto" ,"user" ,"noresize" 其中之一。 | 设置大小调整模式为以下值之一:"auto" ,"user" ,"noresize" 。如未指定rmode 则返回当前的大小调整模式。不同的大小调整模式的效果如下:"auto" : 根据画笔粗细值调整海龟的外观。"user" :根据拉伸因子和轮廓宽度(outline) 值调整海龟的外观,两者是由 shapesize() 设置的。"noresize" :不调整海龟的外观大小。resizemode("user") 会由shapesize() 带参数使用时被调用。 |
形状大小 | shapesize(stretch_wid=None, stretch_len=None, outline=None) turtlesize(stretch_wid=None, stretch_len=None, outline=None) | stretch_wid 正数值stretch_len 正数值outline 正数值 | 返回或设置画笔的属性x/y 拉伸因子和/或轮廓。 设置大小调整模式为"user" 。 当且仅当大小调整模式为"user" 时,海龟会基于其拉伸因子调整外观:stretch_wid 为垂直于其朝向的宽度拉伸因子,stretch_len 为平行于其朝向的长度拉伸因子,outline 决定形状轮廓线的宽度。 |
剪切因子 | shearfactor(shear=None) | shear 数值 (可选) | 设置或返回当前的剪切因子。根据 share 指定的剪切因子即剪切角度的切线来剪切海龟形状。不改变海龟的朝向 (移动方向)。如未指定shear 参数:返回当前的剪切因子即剪切角度的切线,与海龟朝向平行的线条将被剪切。 |
设置倾角 | settiltangle(angle) | angle 一个数值 | 旋转海龟形状使其指向angle 指定的方向,忽略其当前的倾角,不改变海龟的朝向 (移动方向)。3.1 版后已移除. |
倾角 | tiltangle(angle=None) | angle 一个数值 (可选) | 设置或返回当前的倾角。如果指定angle 则旋转海龟形状使其指向angle 指定的方向,忽略其当前的倾角。不改变海龟的朝向 (移动方向)。如果未指定angle :返回当前的倾角,即海龟形状的方向和海龟朝向 (移动方向) 之间的夹角。 |
倾斜 | tilt(angle) | angle 一个数值 | 海龟形状自其当前的倾角转动angle 指定的角度,但不改变海龟的朝向 (移动方向)。 |
变形 | shapetransform(t11=None, t12=None, t21=None, t22=None) | t11 一个数值 (可选)t12 一个数值 (可选)t21 一个数值 (可选)t12 一个数值 (可选) | 设置或返回海龟形状的当前变形矩阵。如未指定任何矩阵元素,则返回以4 元素元组表示的变形矩阵。 否则就根据设置指定元素的矩阵来改变海龟形状,矩阵第一排的值为t11 ,t12 而第二排的值为t21 ,t22 。行列式t11 * t22 - t12 * t21 必须不为零,否则会引发错误。根据指定矩阵修改拉伸因子stretchfactor ,剪切因子shearfactor 和倾角tiltangle 。 |
获取形状多边形 | get_shapepoly() | —— | 返回以坐标值对元组表示的当前形状多边形。这可以用于定义一个新形状或一个复合形状的多个组成部分。 |
from turtle import *hideturtle() # 隐藏海龟
stamp() # 留下一个印章方便比对,隐藏后印章一样可以留下
shape('arrow') # 改变海龟形状
fd(100)
stamp()
shape('turtle')
fd(50)
stamp()
shape('circle')
fd(50)
stamp()
shape('square')
rt(90)
fd(50)
stamp()
shape("triangle")
rt(90)
fd(50)
stamp()
shape("classic")
fd(50)
print(isvisible()) # 海龟是否可见 结果:False
showturtle() # 使海龟可见
print(isvisible()) # 海龟是否可见 结果:False
done()
# 上述自行尝试
3.4使用事件
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
当鼠标点击 | onclick(fun, btn=1, add=None) | fun 一个函数,调用时将传入两个参数表示在画布上点击的坐标。btn 鼠标按钮编号,默认值为 1 (鼠标左键)。add ——True 或False ,如为True 则将添加一个新绑定,否则将取代先前的绑定。 | 将 fun 指定的函数绑定到在此海龟上释放鼠标按键事件。如果fun 值为None ,则移除现有的绑定。 |
当鼠标释放 | onrelease(fun, btn=1, add=None) | fun 一个函数,调用时将传入两个参数表示在画布上点击的坐标。btn 鼠标按钮编号,默认值为 1 (鼠标左键)。add ——True 或False ,如为True 则将添加一个新绑定,否则将取代先前的绑定。 | 将 fun 指定的函数绑定到在此海龟上释放鼠标按键事件。如果fun 值为None ,则移除现有的绑定。 |
当鼠标拖动 | ondrag(fun, btn=1, add=None) | fun 一个函数,调用时将传入两个参数表示在画布上点击的坐标。btn 鼠标按钮编号,默认值为 1 (鼠标左键)。add ——True 或False ,如为True 则将添加一个新绑定,否则将取代先前的绑定。 | 将 fun 指定的函数绑定到在此海龟上释放鼠标按键事件。如果fun 值为None ,则移除现有的绑定。 |
注: 在海龟上移动鼠标事件之前应先发生在此海龟上点击鼠标事件。在此之后点击并拖动海龟可在屏幕上手绘线条 (如果画笔为落下)。
import turtle as t# 函数1 画一个正方形
def fun1(x, y):for i in range(4):t.fd(100)t.lt(90)# 函数2 画一个红色五角星
def fun2(x, y):t.pencolor('red')for i in range(5):t.fd(100)t.rt(144)# 先改变下形状,方便点击,三个事件要去点击海龟对象,点击屏幕没有反应,而且要一个一个执行,看后面解释。
t.shape("turtle")
t.onclick(fun1) # 鼠标点击事件,点击执行fun1,点击事件执行的函数必须包含两个假的参数,不然会报错。
# t.onrelease(fun2) # 鼠标释放事件,点击释放后执行fun2
# t.ondrag(fun2) # 鼠标拖动,拖动后执行fun2,这个结果也会出乎你的意料,尝试下看看
t.done()
说明:以上三个事件,开始我以为点击绘图窗口屏幕就可以执行,但事实并非如此,你会发现点击绘图窗口没有反应,需要点击海龟
画笔才会执行相应事件。原因:这三个函数是Turtle
的函数,对象为Turtle
,我们点击绘图窗口,对象为Screen
窗口对象,而我们函数调用的是Turtle
对象的函数,所以点击绘图窗口不会执行,需要点击海龟
画笔。这是我个人的理解,大家可以评论区讨论下。至于为什么要一个一个执行,你可以尝试下同时执行三个函数,看下结果,可能会出乎你的意料,原因不再解释,思考下Python
的执行原理,就能理解,大家评论区可讨论下,留下自己的看法。如果想实现点击绘图屏幕执行点击事件,请往后面看4.2使用屏幕事件。
3.5特殊海龟方法
作用 | 方法名称 | 详细描述 |
---|---|---|
开始记录多边形 | begin_poly() | 开始记录多边形的顶点。当前海龟位置为多边形的第一个顶点。 |
结束记录多边形 | end_poly() | 停止记录多边形的顶点。当前海龟位置为多边形的最后一个顶点。它将连线到第一个顶点。 |
获取多边形 | get_poly() | 返回最新记录的多边形。 |
克隆 | clone() | 创建并返回海龟的克隆体,具有相同的位置、朝向和海龟属性。 |
获取海龟画笔 | getturtle() getpen() | 返回海龟对象自身。唯一合理的用法:作为一个函数来返回 “匿名海龟”。 |
获取屏幕 | getscreen() | 返回作为海龟绘图场所的TurtleScreen 类对象。该对象将可调用TurtleScreen 方法。 |
设置撤消缓冲区 | setundobuffer(size) | size 一个整型数值或None 。设置或禁用撤销缓冲区。 如果 size 为整数,则开辟一个给定大小的空撤销缓冲区。size 给出了可以通过undo() 方法/函数撤销海龟动作的最大次数。 如果size 为None ,则禁用撤销缓冲区。 |
撤消缓冲区条目数 | undobufferentries() | 返回撤销缓冲区里的条目数。 |
import turtle as tt.begin_poly() # 开始记录多边形的顶点
for i in range(6):t.fd(100)t.rt(60)
t.end_poly() # 停止记录多边形的顶点
print(t.get_poly())
# 结果为多边形顶点坐标:((0.00,0.00), (100.00,0.00), (150.00,-86.60), (100.00,-173.21), (0.00,-173.21), (-50.00,-86.60), (-0.00,-0.00))
s = t.clone() #克隆一个海龟
s.pencolor('red')
s.teleport(200, 200)
t.teleport(-200, 200)
s.begin_poly()
for i in range(5):s.fd(100)s.rt(144)
s.end_poly()
print(s.get_poly())
# 结果:((200.00,200.00), (300.00,200.00), (219.10,141.22), (250.00,236.33), (280.90,141.22), (200.00,200.00))
print(t.getturtle())
print(s.getturtle())
# 可以看到输出两个地址是不一样的
# getscreen()函数后面介绍,设置缓冲去自行尝试。
t.done()
3.6复合形状
要使用由多个不同颜色多边形构成的复合海龟形状,你必须明确地使用辅助类Shape
,具体步骤如下:
1、创建一个空Shape
对象,类型为"compound"
。
2、可根据需要使用addcomponent()
方法向此对象添加多个组件。
3、接下来将Shape
对象添加到Screen
对象的形状列表并使用它。
方法名称 | 参数 |
---|---|
addcomponent(poly, fill, outline=None) | poly 一个多边形,即由数值对构成的元组fill 一种颜色,将用来填充poly 指定的多边形outline 一种颜色,用于多边形的轮廓 (如有指定)。 |
备注:Shape
类在register_shape()
方法的内部以多种方式使用。应用程序编写者只有在使用上述的复合形状时才需要处理Shape
类。
import turtle as ts = t.Shape("compound") # 创建Shape类对象,类型为"compound"
poly1 = ((0, 0), (10, -5), (0, 10), (-10, -5)) # 复合图形1的顶点坐标
s.addcomponent(poly1, "red", "blue") # 将复合图形1添加到Shape对象
poly2 = ((0, 0), (10, -5), (-10, -5)) # 复合图形2的顶点坐标
s.addcomponent(poly2, "blue", "red") # 将复合图形1添加到Shape对象
t.register_shape("myshape", s) # 将复合图形添加至TurtleScreen的形状列表
t.shape("myshape") # 选用添加的复合图形
t.stamp() # 设置一个印章检查是否添加成功
t.done()
四、TurtleScreen/Screen 方法
TurtleScreen
是基本的海龟绘图区域。Screen
是TurtleScreen
的子类,并包括一些额外方法用来管理其外观(包括大小和标题)及行为。
4.1窗口控制
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
背景颜色 | bgcolor(*args) | args 一个颜色字符串或三个取值范围0..colormode 内的数值或一个取值范围相同的数值3元组。 | 设置或返回TurtleScreen 的背景颜色。 |
背景图片 | bgpic(picname=None) | picname 一个字符串, gif-文件名, "nopic" , 或None 。 | 设置背景图片或返回当前背景图片名称。如果picname 为一个文件名,则将相应图片设为背景。如果picname 为"nopic" ,则删除当前背景图片。如果picname 为 None ,则返回当前背景图片文件名。 |
重置 | clearscreen() | —— | 从中删除所有海龟的全部绘图。将已清空的TurtleScreen 重置为初始状态: 白色背景,无背景片,无事件绑定并启用追踪。 |
重置 | resetscreen() | —— | 重置屏幕上的所有海龟为其初始状态。 |
屏幕大小 | screensize(canvwidth=None, canvheight=None, bg=None) | canvwidth 正整型数,以像素表示画布的新宽度值。canvheight 正整型数,以像素表示画面的新高度值。bg 颜色字符串或颜色元组,新的背景颜色。 | 如未指定任何参数,则返回当前的 (canvaswidth, canvasheight) 。否则改变作为海龟绘图场所的画布大小。不改变绘图窗口。要观察画布的隐藏区域,可以使用滚动条。通过此方法可以令之前绘制于画布之外的图形变为可见。也可以用来寻找意外逃走的海龟。 |
设置世界坐标系 | setworldcoordinates(llx, lly, urx, ury) | llx 一个数值, 画布左下角的x 坐标。lly 一个数值, 画布左下角的y 坐标。urx 一个数值, 画面右上角的x 坐标。ury 一个数值, 画布右上角的y 坐标。 | 设置用户自定义坐标系并在必要时切换模式为"world" 。这会执行一次screen.reset() 。如果"world" 模式已激活,则所有图形将根据新的坐标系重绘。注意: 在用户自定义坐标系中,角度可能显得扭曲。 |
import turtle as tt.bgcolor('yellow') # 设置窗口背景为黄色
t.bgpic('R-C.gif') # 设置背景图片,注意图片类型为gif,图片与Python文件同目录,或者为图片绝对路径
# t.clearscreen() # 清空屏幕
# t.resetscreen() # 重置屏幕海龟为其初始状态。
t.screensize(1000, 1000, 'red') # 设置画布大小及背景颜色
t.done()
说明:
screensize()
只能设置画布大小,不能改变窗口的大小,想要改变窗口大小,请看后面4.5Screen
专有方法setup()
。
4.2动画控制
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
延迟 | delay(delay=None) | delay 正整型数 | 设置或返回以毫秒数表示的延迟值delay 。(这约等于连续两次画布刷新的间隔时间。) 绘图延迟越长,动画速度越慢。 |
追踪 | tracer(n=None, delay=None) | n 非负整型数。delay 非负整型数。 | 启用/禁用海龟动画并设置刷新图形的延迟时间。如果指定 n 值,则只有每第n 次屏幕刷新会实际执行。(可被用来加速复杂图形的绘制。) 如果调用时不带参数,则返回当前保存的n 值。第二个参数设置延迟值 (参见delay() )。 |
更新 | update() | —— | 执行一次TurtleScreen 刷新。在禁用追踪时使用。 |
delay()
延迟:
import turtle as t# 绘制一个五角星
def fun():for i in range(5):t.fd(100)t.rt(144)print(t.delay()) # 输出当前画布刷新时间间隔(延迟值),结果:10
t.delay(200) # 可以看到绘制速度变慢了
# t.speed(1) # 使用speed()函数同样能使速度变慢,但两者是有不同的,可以仔细观察下。
fun()
t.done()
tracer()
追踪:
import turtle as tprint(t.tracer()) # 输出当前的n值,结果:1
t.tracer(0) # 禁用海龟动画,可以尝试将n设置成不同的值,不执行刷新看下结果,tracer(0)等同于tracer(False),tracer(1)等同于tracer(True)
for i in range(5):t.fd(100)t.rt(144)
# t.update() # 禁用动画后,不执行刷新,不显示绘图的完整结果,也可以通过启用,显示完整绘图结果。
t.done()
# 可以用来制作动画效果,可以看后面实例
4.2使用屏幕事件
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
监听 | listen(xdummy=None, ydummy=None) | —— | 设置焦点到TurtleScreen (以便接收按键事件)。使用两个Dummy 参数以便能够传递 listen() 给onclick 方法。 |
当键盘按下并释放 | onkey(fun, key) onkeyrelease(fun, key) | fun 一个无参数的函数或None 。key 一个字符串:键 (例如 "a" ) 或键标 (例如"space" ) | 绑定fun 指定的函数到按键释放事件。如果fun 值为None ,则移除事件绑定。注:为了能够注册按键事件,TurtleScreen 必须得到焦点。(参见listen() 方法。) |
当键盘按下 | onkeypress(fun, key=None) | fun 一个无参数的函数或None 。key 一个字符串:键 (例如 "a" ) 或键标 (例如"space" ) | 绑定fun 指定的函数到指定键的按下事件。如未指定键则绑定到任意键的按下事件。注: 为了能够注册按键事件,必须得到焦点。(参见listen() 方法。) |
当点击屏幕 | onclick(fun, btn=1, add=None) onscreenclick(fun, btn=1, add=None) | fun 一个函数,调用时将传入两个参数表示在画布上点击的坐标。btn 鼠标按钮编号,默认值为1 (鼠标左键)add ——True 或False ,如为True 则将添加一个新绑定,否则将取代先前的绑定。 | 绑定fun 指定的函数到鼠标点击屏幕事件。如果fun 值为None ,则移除现有的绑定。备注:此TurtleScreen 方法作为全局函数时只有一个名字onscreenclick 。全局函数onclick 所对应的是Turtle 方法onclick 。 |
当达到定时 | ontimer(fun, t=0) | fun 一个无参数的函数。t 一个 >= 0的数值。 | 安装一个计时器,在t 毫秒后调用fun 函数。 |
主循环 | mainloop() done() | —— | 开始事件循环,调用Tkinter 的mainloop 函数。必须作为一个海龟绘图程序的结束语句。如果一个脚本是在以n 模式 (无子进程) 启动的IDLE 中运行时,不可使用,用于实现海龟绘图的交互功能。 |
import turtle as tdef fun1():for i in range(5):t.fd(100)t.rt(144)t.listen() # 设置焦点到窗口,文档解释里有两个假参数,是为了方便在onclick()里面调用listen()。
t.onkey(fun1, 'a') # 绑定fun指定的函数到按键释放事件
t.onkeypress(fun1, 'm') # 绑定fun指定的函数到指定键的按下事件
t.ontimer(fun1, 1000) # 安装一个计时器,在t毫秒后调用fun函数
t.done()
接下来看下屏幕点击事件:
首先介绍onscreenclick()
:
import turtle as tdef fun1(x, y):for i in range(5):t.fd(100)t.rt(144)t.onscreenclick(fun1) # 点击窗口空白地方,海归会执行fun1,在海龟当前绘制图形,注意:执行的函数需要设置两个假的参数,不然会报错。
t.done()
# 可以通过调用goto()函数实现:鼠标点哪里,海龟移动到哪里,可以看下边实例。
再看一下onclick()
这个函数:
import turtle as ts = t.getscreen() # 获取窗口TurtleScreen对象
s.onclick(t.goto) # 通过窗口类对象调用onclick()函数,执行goto(),实现在绘图窗口点哪里海龟移动到哪里。
t.done()
前面我们已经对t.onclick()
进行了测试,正如文档所述,直接使用onclik()
,调用的是Turtle
对象的onclick()
函数,并非TurtleScreen
对象的onclick()
函数。TurtleScreen
对象的onclick()
函数不能作为全局函数使用。
4.3设置与特殊方法
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
设置海龟模式 | mode(mode=None) | mode 字符串"standard" ,"logo" 或"world" 其中之一。 | 设置海龟模式 ("standard" ,"logo" 或 "world" ) 并执行重置。如未指定模式则返回当前的模式。"standard" 模式与旧的turtle 兼容。"logo" 模式与大部分Logo 海龟绘图兼容。"world" 模式使用用户自定义的"世界坐标系" 。注意: 在此模式下,如果x/y 单位比率不等于1 则角度会显得扭曲。模式——初始海龟朝向——正数角度 "standard" ——朝右 (东)——逆时针"logo" ——朝上 (北)——顺时针 |
颜色模式 | colormode(cmode=None) | cmode 数值1.0 或255 其中之一。 | 返回colormode 或将其设为1.0 或255 。 后续表示三原色的r, g, b 值必须在0..cmode 范围之内。 |
获取画布 | getcanvas() | —— | 返回此TurtleScreen 的Canvas 对象。供了解Tkinter 的Canvas 对象内部机理的人士使用。 |
获取形状 | getshapes() | —— | 返回所有当前可用海龟形状的列表。 |
添加形状 | register_shape(name, shape=None) addshape(name, shape=None) | (1)name 为一个gif 文件的文件名,shape 为 None :安装相应的图像形状。(2) name 为指定的字符串,shape 为由坐标值对构成的元组:安装相应的多边形形状。(3) name 为任意字符串而shape 为 (复合)Shape 对象:安装相应的复合形状。 | 将一个海龟形状加入TurtleScreen 的形状列表。只有这样注册过的形状才能通过执行shape(shapename) 命令来使用。 |
所有海龟 | turtles() | —— | 返回屏幕上的海龟列表。 |
窗口高度 | window_height() | —— | 返回海龟窗口的高度。 |
窗口宽度 | window_width() | —— | 返回海龟窗口的宽度。 |
import turtle as tprint(t.mode()) # 输出当前海龟模式,结果:standard
t.mode('logo') # 设置海龟模式logo
t.fd(100)
print(t.colormode()) # 输出当前颜色模式,结果:1.0
print(t.getshapes()) # 输出当前可用海龟形状,结果:['arrow', 'blank', 'circle', 'classic', 'square', 'triangle', 'turtle']
print(t.turtles()) # 返回屏幕上的海龟列表
print(t.window_width()) # 返回海龟窗口的宽度。
print(t.window_height()) # 返回海龟窗口的高度。
# 画一个五角星作为一个新的海龟形状
t.begin_poly() # 开始记录五角星顶点坐标
for i in range(5):t.fd(50)t.rt(144)
t.end_poly() # 结束记录五角星顶点坐标
t.addshape("star", t.get_poly()) # 将五角星添加为海龟形状
t.shape('star') # 将海龟形状设置为刚添加的五角星
t.fd(100)
t.done()
4.4 输入方法
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
文本输入 | textinput(title, prompt) | title 字符串。prompt 字符串。 | 弹出一个对话框窗口用来输入一个字符串。形参title 为对话框窗口的标题,prompt 为一条文本,通常用来提示要输入什么信息。返回输入的字符串。如果对话框被取消则返回None 。 |
数字输入 | numinput(title, prompt, default=None, minval=None, maxval=None) | title 字符串。prompt 字符串。default 数值 (可选)。minval 数值 (可选)。maxval 数值 (可选)。 | 弹出一个用于输入数值的对话框窗口。title 是对话框窗口的标题,prompt 是通常用来描述要输入的数字信息的文本。 default :默认值,minval :可输入的最小值,maxval ::可输入的最大值。 如果给出minval .. maxval 则输入的数值必须在此范围以内。 如未给出,则将发出提示并且让话框保持打开以便修正。 返回输入的数值。 如果对话框被取消,则返回None 。 |
文本输入示例:
import turtle as t
# 实现交互,输入五边形绘制一个五边形,你可以尝试更复杂的例子。
s = t.textinput("绘制五边形:","请输入‘五边形’:")
if s == '五边形':t.circle(100,360,5)
else:t.write("你输入有误")
t.done()
数字输入示例:
import turtle as t
# 根据输入的数字绘制多边形
s = t.numinput("绘制多边形:", "请输入你想绘制的多边形:", 3, 3,10)
a = int(s)
if 3 <= a < 10:t.circle(100, 360, a)
else:t.write("你的输入不符合要求")
t.done()
4.5 Screen 专有方法
作用 | 方法名称 | 参数 | 详细描述 |
---|---|---|---|
退出 | bye() | —— | 关闭海龟绘图窗口。 |
当点击时退出 | exitonclick() | —— | 将bye() 方法绑定到Screen 上的鼠标点击事件。如果配置字典中"using_IDLE" 的值为False (默认值) 则同时进入主事件循环。注:如果启动IDLE 时使用了n 开关 (无子进程),turtle.cfg 中此数值应设为True 。在此情况下IDLE 本身的主事件循环同样会作用于客户脚本。 |
设置 | setup(width=_CFG['width'], height=_CFG['height'], startx=_CFG['leftright'], starty=_CFG['topbottom']) | width 如为一个整型数值,表示大小为多少像素,如为一个浮点数值,则表示屏幕的占比;默认为屏幕的 50%。height 如为一个整型数值,表示高度为多少像素,如为一个浮点数值,则表示屏幕的占比;默认为屏幕的 75%。startx 如为正值,表示初始位置距离屏幕左边缘多少像素,负值表示距离右边缘,None 表示窗口水平居中。starty 如为正值,表示初始位置距离屏幕上边缘多少像素,负值表示距离下边缘,None 表示窗口垂直居中。 | 设置主窗口的大小和位置。默认参数值保存在配置字典中,可通过turtle.cfg 文件进行修改。 |
标题 | title(titlestring) | titlestring 一个字符串,显示为海龟绘图窗口的标题栏文本。 | 设置海龟窗口标题为titlestring 指定的文本。 |
import turtle as tt.title("Turtle绘图") # 设置绘图窗口标题
t.setup(500, 500, 100) # 设置绘图窗口大小及在显示屏的位置
t.fd(100)
# t.bye() # 执行会立即关闭绘图窗口
t.exitonclick() # 当鼠标点击绘图窗口时,关闭绘图窗口。
五、公共类
类名 | 参数 | 说明 |
---|---|---|
RawTurtle(canvas) RawPen(canvas) | canvas 一个tkinter.Canvas ,ScrolledCanvas 或TurtleScreen | 创建一个海龟。海龟对象具有Turtle/RawTurtle方法 一节所述的全部方法。 |
Turtle | —— | RawTurtle 的子类,具有相同的接口,但其绘图场所为默认的Screen 类对象,在首次使用时自动创建。 |
TurtleScreen(cv) | cv 一个tkinter.Canvas | 提供面向屏幕的方法如bgcolor() 等。 |
Screen | —— | TurtleScreen 的子类,增加了四个方法。 |
ScrolledCanvas(master) | master – 可容纳ScrolledCanvas 的Tkinter 部件,即添加了滚动条的Tkinter-canvas | 由Screen 类使用,使其能够自动提供一个ScrolledCanvas 作为海龟的绘图场所。 |
Shape(type_, data) | type_ – 字符串"polygon" ,"image" , "compound" 其中之一 | 实现形状的数据结构。(type_, data) 必须遵循以下定义: type_——data "polygon" ——一个多边形元组,即由坐标值对构成的元组"image" ——一个图片 (此形式仅限内部使用!)"compound" ——None (复合形状必须使用addcomponent() 方法来构建) |
Vec2D(x, y) | —— | 一个二维矢量类,用来作为实现海龟绘图的辅助类。也可能在海龟绘图程序中使用。派生自元组,因此矢量也属于元组。提供的运算 (a ,b 为矢量,k 为数值):a + b 矢量加法a - b 矢量减法a * b 内积k * a 和a * k 与标量相乘abs(a) ,a 的绝对值a.rotate(angle) 旋转 |
六、应用实例
turtledemo
包汇集了一组演示脚本。这些脚本可以通过命令打开所提供的演示查看器运行和查看。这里对其中一个演示脚本进行解析。后面提供如何通过命令打开演示脚本。下面是对round_dance
演示脚本的解析(部分地方与原脚本稍有改动)。
import turtle as t# 此演示脚本原理:
# 首先利用循环创建复合图形并添加至TurtleScreen的形状列表
# 利用循环克隆15个复合图形的海龟对象。
# 再利用循环将15个海龟放置在不同位置上
# 利用循环改变15个海龟的倾斜角度并使其转动达到动画效果。# 停止动画函数,设置全局变量running = False,启动后点击任意键停止动画
def stop():global runningrunning = False# 主函数
def main():global runningt.clearscreen() # 清屏t.bgcolor("gray10") # 设置背景颜色t.tracer(False) # 禁用追踪t.shape("triangle") # 设置海龟形状为“triangle”f = 0.793402 # 系数phi = 9.064678 # 海龟倾斜角度s = 5 # 初始图形形状大小c = 1 # 设置初始填充颜色系数# 创建复合形状sh = t.Shape("compound") # 创建一个名为“compound”的海龟对象for i in range(10): # 利用循环绘制复合图形t.shapesize(s) # 设置海龟大小p = t.get_shapepoly() # 获取当前海龟形状的坐标值s *= f # 将海龟大小按f缩小c *= f # 改变初始填充颜色系数t.tilt(-phi) # 将海龟倾斜-phish.addcomponent(p, (c, 0.25, 1 - c), "black") # 添加每一个形状组件添加到Shape对象t.register_shape("multitri", sh) # 将海龟形状加入TurtleScreen的形状列表# 创建舞者(转动的图像,称为舞者)t.shapesize(1) # 设置海龟大小t.shape("multitri") # 设置海龟形状为“multitri”t.up() # 将画笔抬起t.setpos(0, -200) # 海龟移动到一个绝对坐标dancers = [] # 创建舞者数组for i in range(180): # 利用循环绘制15个舞者t.fd(7)t.tilt(-4) # 将海龟倾斜-4t.lt(2)t.update() # 前边禁用了追踪,在这里刷新窗口if i % 12 == 0: # 当i是12的倍数时,克隆一个海龟,并添加到舞者数组dancers.append(t.clone()) # 克隆一个海龟,并添加到舞者数组t.home() # 回到原点# 使图形转动起来running = Truet.onkeypress(stop) # 创建键盘点击事件,点击任意键动画停止t.listen() # 监听cs = 1 # 设置初始放大系数while running: # 创建循环使图形转动起来angle = -4for dancer in dancers: # 循环画出舞者数组里的15个舞者dancer.fd(7)dancer.lt(2)dancer.tilt(angle) # 旋转angleangle = -4 if angle > 0 else 2 # 每次更改旋转角度if cs < 12:t.rt(4) # 原点图形右转4度t.shapesize(cs) # 将原点图形按cs放大cs *= 1.005t.update() # 刷新窗口return "DONE!" # 循环结束,输出Done!if __name__ == '__main__':print(main())t.mainloop()
下边介绍如何打开turtledemo
包汇集的演示脚本。管理员身份打开终端(cmd命令窗口)或在Pycharm的命令窗口,输入以下代码:
python -m turtledemo
回车(Enter)执行,出现以下窗口:
点击左上角Example
查看选择演示脚本。点击START
开始执行脚本。如果不想本地打开可以看我另一篇文章,Turtle绘图案例。
到此,Turtle绘图就介绍完毕了,发挥你的想象力,去创作吧!