turtle库是python的标准库_Python标准库程序框架——turtle海龟绘图

Python标准库程序框架——turtle海龟绘图

? 我想,科普最好的对象是小朋友,那么就写一下被移植到Python标准库里的turtle库吧。以下代码基于Python 3.8.1。

概述

? 海龟绘图,最初来自于 Wally Feurzeig, Seymour Papert 和 Cynthia Solomon 于 1967 年所专门为引导儿童学习编程创造的 Logo 编程语言。turtle库的实现过程很形象,犹如一只海龟在画布上画画。海龟绘图很适合用来培养小朋友对编程的学习兴趣。

? 试想象一下,在一块画布上,起始位置在x-y平面的(0,0)点,执行```import turtle``来召唤一只拿着画笔的海龟(也就是一个点),再利用turtle库里一系列的指令(方法)来指挥这只海龟来爬。最后通过组合这些指令,海龟爬行的轨迹将可以轻松地绘制出精美的形状和图案。并且通过对应函数,能按我们的要求把海龟的轨迹在显示设备上输出显示。

? 目前的turtle模块是基于Python标准发行版2.5重新编写和扩展,并与原模块100%兼容。因此能以交互方式使用模块的所有命令、类和方法。

? turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。具体如下:

面向对象:

TurtleScreen 类定义图形窗口作为绘图海龟的运动场。它的构造器需要一个 tkinter.Canvas 或 ScrolledCanvas 作为参数。应在 turtle 作为某个程序的一部分的时候使用。

Screen() 函数返回一个 TurtleScreen 子类的单例对象。此函数应在 turtle 作为独立绘图工具时使用。作为一个单例对象,其所属的类是不可被继承的。

TurtleScreen/Screen的所有方法还存在对应的函数,即作为面向过程的接口组成部分。

RawTurtle 类定义海龟对象在TurtleScreen上绘图。它的构造器需要一个 Canvas, ScrolledCanvas 或 TurtleScreen作为参数,以指定 RawTurtle对象在哪里绘图。

从 RawTurtle派生出子类Turtle,该类对象在Screen实例上绘图,若实例不存在则会自动创建。

RawTurtle/Turtle 的所有方法也存在对应的函数,即作为面向过程的接口组成部分

面向过程:

? 过程式接口提供与Screen 和Turtle类的方法相对应的函数。函数名与对应的方法名相同。当Screen类的方法对应函数被调用时会自动创建一个Screen 对象。当Turtle类的方法对应函数被调用时会自动创建一个 (匿名的)Turtle 对象。

? 当需要屏幕上有多个海龟的时候,就必须使用面向对象的接口。

可用的turtle和Screen方法

? 如前文所说,我们通过import turtle召唤了一只拿着画笔的海龟,海龟的的动作以及画笔都是通过方法来控制的。同时,作为一只被召唤出来的二维生物,我们作为比他高维的生物,自然有很多降维操纵甚至打击的方法。从某种角度上来说,我们对这些turtle有近乎神迹般的操纵和控制。 然而并不是。具体方法如下。

RawTurtle/Turtle方法和对应函数

以下都是使用Turtle类的实例,命名为turtle。

海龟动作

? 我们能控制海龟的前进后退,左转右转,爬行速度,甚至能让海龟像赛亚人或者哈利波特里的巫师一样学会幻影移行,同时能随时获知海龟的位置信息。

移动和绘制

forward(distance) :前进distance距离

>>> turtle.position()

(0.00,0.00)

>>> turtle.forward(distance)

>>> turtle.position()

(distance,0.00)

>>> turtle.forward(distance)

>>> turtle.position()

(distance+distance,0.00)

backward(distance) :后退distance距离

>>> turtle.position()

(0.00,0.00)

>>> turtle.backward(distance)

>>> turtle.position()

(-distance,0.00)

right(angle) :右转angle个单位

>>> turtle.heading()

22.0

>>> turtle.right(angle)

>>> turtle.heading()

22.0-angle+360.0

left(angle):左转angle个单位

>>> turtle.heading()

22.0

>>> turtle.left(angle)

>>> turtle.heading()

22.0+angle

goto(x,y=None) | setposition(x,y=None) :前往/定位一个绝对坐标

setx(x) 设置x坐标

sety(y) 设置y坐标

setheading(to_angle) 设置朝向

import turtle

from turtle import *

color('red', 'yellow')

turtle.setheading(90)

turtle.heading()

done()

home() 返回原点

circle(radius, extent=None, steps=None) 画圆

import turtle

from turtle import *

color('red', 'yellow')

turtle.home()

turtle.position()

turtle.heading()

turtle.circle(50)

turtle.position()

turtle.heading()

turtle.circle(120, 180)  # draw a semicircle

turtle.position()

turtle.heading()

done()

dot(size=None, color) 画点

stamp() 印章

clearstamp(stampid) 清除印章

clearstamps(n=None) 清除多个印章

undo() :撤消海龟最近一个或多个动作

speed(speed=None) :控制海龟移动速度

获取海龟的状态

position() | pos() 位置:返回海龟当前的坐标

towards() :返回海龟朝向

xcor() :返回海龟x坐标

ycor() :返回海龟y坐标

distance() 返回从海龟位置到另一位置的距离

画笔控制

? 同时,海龟对于我们来说只是用来画画的工具龟,所以我们对于它用来画轨迹的画笔也有相应的方法来控制。

绘图状态

pendown() 画笔落下:海龟移动时将画线

penup() 画笔抬起:海龟移动时不画线

pensize(width=None) 画笔粗细

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": 数值

isdown() 画笔是否落下:判断画笔是否落下,落下返回True,抬起返回False。

颜色控制

pencolor(*args) :返回和设置画笔颜色

允许四种不同的输入格式:

pencolor():返回以颜色描述字符串或元组表示的当前画笔颜色;

pencolor(colorstring):设置画笔颜色为colorstring指定的Tk颜色描述字符串;

pencolor((r,g,b)):设置画笔颜色为以r,g,b元组表示的RGB颜色;

pencolor(r,g,b):设置画笔颜色为以r,g,b表示的RGB颜色;

fillcolor(*args) :返回和设置填充颜色

同pencolor(*args)一样,有四种不同的输入格式:

fillcolor():返回以颜色描述字符串或元组表示的当前填充颜色;

fillcolor(colorstring):设置填充颜色为colorstring指定的Tk颜色描述字符串;

fillcolor((r,g,b)):设置填充颜色为以r,g,b元组表示的RGB颜色;

fillcolor(r,g,b):设置填充颜色为以r,g,b表示的RGB颜色;

color(* args) 返回或设置画笔颜色和填充颜色

color()允许多种输入格式:

color():返回以一对颜色描述字符串或元组表示的当前画笔颜色和填充颜色;

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),rbg格式也与值类似;

填充

filling() 是否填充

begin_fill() 开始填充

end_fill() 结束填充

更多绘图控制

reset() 重置:从屏幕中删除海龟的绘图,同时海龟返回原点并重置所有变量为默认值

clear() 清空:从屏幕中只删除海龟的绘图

write(*arg, move=False, align="left", font=("Arial",8,"normal")) :书写文本

write()的参数具体为:

arg -- 要书写到TurtleScreen的对象'

move -- True/False

align -- 字符串"left","center"或"right"

font -- 一个三元组(fontname, fontsize, fonttype)

海龟状态

可见性

showturtle() 显示海龟

hideturtle() 隐藏海龟:隐藏海龟可显著加快绘制速度

isvisible() 检查是否可见

外观

shape(name=None)

设置海龟形状为name指定的形状名,如未指定形状名则返回当前的形状名

resizemode(rmode=None) :大小调整模式

rmode为以下值之一:"auto","user","noresize";

不同的大小调整模式有不同的效果如下:

auto: 根据画笔的粗细值调整海龟外观;

user: 根据拉伸因子和轮廓宽度值调整海龟的外观,两者通过shapesize()设置,user模式会在shapesize()带参数调用时生效;

noresize:不调整海龟的外观大小;

shapesize(stretch_wid=None, strech_len=None, outline=None) 形状大小

shearfactor(shear=None) 剪切因子

tiltangle(angle=None) :设置或返回当前的倾角

tilt(angle) :海龟形状自其当前倾角转动angle的角度

shapetransform(t11=None, t12=None, t21=None, t22=None) :设置或返回海龟形状的当前变形矩阵

get_shapepoly() 获取形状多边形

使用事件

onclick(fun, btn=1, add=None)

当鼠标点击,触发事件fun函数并传入两个参数表示在画布上点击的坐标,

fun -- 函数,调用时传入两个参数, 以表示在画布上点击的坐标;

btn -- 鼠标按钮编号,默认值为1,即鼠标左键;

add -- True或False, 为False将取代先前的绑定

onrelease(fun, btn=1,add=None) 当鼠标释放

当鼠标按键释放,触发事件,三个参数同onclick()

ondrag(fun, btn=1,add=None) 当鼠标拖动

当鼠标移动,触发事件,三个参数同上

特殊海龟方法

begin_poly() 开始记录多边形

end_poly() 结束记录多边形

get_poly() 获取多边形

clone() 克隆

getturtle() | getpen() 获取海龟画笔

getscreen() 获取屏幕

setundobuffer() 设置撤消缓冲区

undobufferentries() 撤消缓冲区条目数

TurtleScreen/Screen方法及对应函数*

窗口控制

bgcolor(*args) :设置或返回背景颜色

bgpic(picname=None) 设置背景图片或返回当前背景图片名称

picname可以为字符串(若为文件名,则将相应图片设为背景),nopic(删除当前背景图片),None(返回当前背景图片文件名)

clear() | clearscreen() 清屏

reset() | resetscreen() 重置

screensize(canvwidth=None, canvheight=None, bg=None) 屏幕大小

canviwidth -- 以像素表示画布的新宽度值

canvheight -- 以像素表示画面的新高度值

bg -- 以颜色字符串或颜色元组表示的新背景颜色

setworldcoordinates(llx, lly, urx, ury) 设置世界坐标系

动画控制

delay() 延迟

tracer(n=None, delay=None)

启用/禁用海龟动画并设置刷新图形的延迟时间

update() :执行一次TurtleScreen刷新

使用屏幕事件

listen(xdummy=None, ydummy=None) :

设置焦点到TurtleScreen, 以接收按键事件

onkey(fun, key)

绑定指定fun函数到按键释放事件

onkeypress(fun, key)

绑定指定fun函数到指定按键的按下事件

onclick(fun, btn=1, add=None)

绑定指定fun函数到指定按键的点击屏幕事件

ontimer(fun, t=0)

安装一个计时器,在t毫秒后,调用指定fun函数

mainloop() | done() 主循环

调用Tkinter的mainloop函数

输入方法

textinput(title, prompt) 文本输入

弹出一个对话框窗口用来输入一个字符串。

title -- 对话框窗口的标题

prompt -- 一条用来描述要输入的信息的文本

numinput(title, prompt, default=None, minval=None, maxval=Non) 数字输入

弹出一个对话框窗口用来输入一个数值。

title -- 对话框窗口的标题

prompt -- 一条用来描述要输入的数值信息的文本

default -- 默认值

minval -- 可输入的最小值

maxval -- 可输入的最大值

Screen 专有方法

bye()

关闭海龟绘图窗口

exitonclick()

将bye()方法绑定到Screen上的鼠标事件

setup(width=CFG["width"], height= CFG["height"],startx=CFG["leftright"],starty=_CFG["topbottom"])

设置主窗口的大小和位置。

width -- 数值为整形则表示大小的像素值,若为浮点数则表示屏幕的占比,默认为屏幕50%

height -- 数值为整形表示高度的像素值,若为浮点数则表示屏幕的占比,,默认为屏幕75%

startx -- 正值表示初始位置距离屏幕左边缘像素值,负值表示距离右边缘,None表示窗口水平居中

starty -- 正值表示初始位置距离屏幕上边缘多少像素,负值表示距离下边缘,None表示窗口垂直居中

title(titlestring)

设置海龟窗口标题为title string指定的文本

结语

? 本想着写一篇面向儿童的科普文。写着写着,被Python官方的手册带偏了,权当是给教儿童科普编程的人小小的对turtle方法的归类和介绍吧。

? python是一门简约但不简单的语言,在python的编译器中输入import this执行后出来的《Python之禅》中,从Python准则的诗句中,可见一斑。Python是一样工具,更是一门语言,它应该很有趣。而通常有趣到极致的代名词是儿童。同时,一门语言想要延续,就应当能吸引年轻的血液。而Python标准库下的turtle模块,应该就是实现这两种功能的法宝之一。

? 一九九几年和两千零几年说的信息化,再过几天就是2020年,离2000年也已过二十年,现在讨论的和追捧的也已经是智能化。离1946年2月14日也就快74年时间。二十年时间超过了计算机寿命的四分之一,而计算机家用早已推广,还捧出来一个世界首富。可是,对于应用计算机最为核心的编程,到目前还有很多人不掌握。苹果ceo库克拜访上海某小学推广swift语言和社交媒体提到某个学编程的儿童成为了新闻,这种事情个人认为是不正常的。

? 套用某部电影说的话”21世纪最缺的是人才“。虽然最不缺和不值钱的貌似也是人才。人才从哪里来?人才是从小培养的。而如果有那么一种编程语言,能让小朋友都能学会,并且通过这个语言以后能更容易学习更多其他的语言,无疑是非常好的。对于儿童能学习知识,也能方便生活。对于社会,如果这种语言是如swift一样有盈利公司开发的,公司能赚小朋友父母钱;如果这种语言是开源的,那么整个社会的编程水平总会提高那么一丢丢,这就简直是造福全世界了。

? 最后,附上一个搜集资料(https://www.cnblogs.com/yangbin1212/p/9763936.html)时看到的使用turtle画出来的有趣的《小猪佩奇》python源代码吧。

? 完成效果图如下:

"""

@time :12/30/2019

@author: menkwan

"""

# coding:utf-8

import turtle as t

# 绘制小猪佩奇

# =======================================

t.pensize(4)

t.hideturtle()

t.colormode(255)

t.color((255, 155, 192), "pink")

t.setup(840, 500)

t.speed(10)

# 鼻子

t.penup()

t.goto(-100,100)

t.pendown()

t.seth(-30)

t.begin_fill()

a = 0.4

for i in range(120):

if 0 <= i < 30 or 60 <= i < 90:

a = a+0.08

t.left(3)  # 向左转3度

t.forward(a)  # 向前走a的步长

else:

a = a-0.08

t.left(3)

t.forward(a)

t.end_fill()

t.penup()

t.seth(90)

t.forward(25)

t.seth(0)

t.forward(10)

t.pendown()

t.pencolor(255, 155, 192)

t.seth(10)

t.begin_fill()

t.circle(5)

t.color(160, 82, 45)

t.end_fill()

t.penup()

t.seth(0)

t.forward(20)

t.pendown()

t.pencolor(255, 155, 192)

t.seth(10)

t.begin_fill()

t.circle(5)

t.color(160, 82, 45)

t.end_fill()

# 头

t.color((255, 155, 192), "pink")

t.penup()

t.seth(90)

t.forward(41)

t.seth(0)

t.forward(0)

t.pendown()

t.begin_fill()

t.seth(180)

t.circle(300, -30)

t.circle(100, -60)

t.circle(80, -100)

t.circle(150, -20)

t.circle(60, -95)

t.seth(161)

t.circle(-300, 15)

t.penup()

t.goto(-100, 100)

t.pendown()

t.seth(-30)

a = 0.4

for i in range(60):

if 0 <= i < 30 or 60 <= i <90:

a = a+0.08

t.left(3)  # 向左转3度

t.forward(a)  # 向前走a的步长

else:

a = a-0.08

t.left(3)

t.forward(a)

t.end_fill()

# 耳朵

t.color((255, 155, 192), "pink")

t.penup()

t.seth(90)

t.forward(-7)

t.seth(0)

t.forward(70)

t.pendown()

t.begin_fill()

t.seth(100)

t.circle(-50, 50)

t.circle(-10, 120)

t.circle(-50, 54)

t.end_fill()

t.penup()

t.seth(90)

t.forward(-12)

t.seth(0)

t.forward(30)

t.pendown()

t.begin_fill()

t.seth(100)

t.circle(-50, 50)

t.circle(-10, 120)

t.circle(-50, 56)

t.end_fill()

#眼睛

t.color((255, 155, 192), "white")

t.penup()

t.seth(90)

t.forward(-20)

t.seth(0)

t.forward(-95)

t.pendown()

t.begin_fill()

t.circle(15)

t.end_fill()

t.color("black")

t.penup()

t.seth(90)

t.forward(12)

t.seth(0)

t.forward(-3)

t.pendown()

t.begin_fill()

t.circle(3)

t.end_fill()

t.color((255, 155, 192), "white")

t.penup()

t.seth(90)

t.forward(-25)

t.seth(0)

t.forward(40)

t.pendown()

t.begin_fill()

t.circle(15)

t.end_fill()

t.color("black")

t.penup()

t.seth(90)

t.forward(12)

t.seth(0)

t.forward(-3)

t.pendown()

t.begin_fill()

t.circle(3)

t.end_fill()

# 腮

t.color((255, 155, 192))

t.penup()

t.seth(90)

t.forward(-95)

t.seth(0)

t.forward(65)

t.pendown()

t.begin_fill()

t.circle(30)

t.end_fill()

# 嘴

t.color(239, 69, 19)

t.penup()

t.seth(90)

t.forward(15)

t.seth(0)

t.forward(-100)

t.pendown()

t.seth(-80)

t.circle(30, 40)

t.circle(40, 80)

# 身体

t.color("red", (255, 99, 71))

t.penup()

t.seth(90)

t.forward(-20)

t.seth(0)

t.forward(-78)

t.pendown()

t.begin_fill()

t.seth(-130)

t.circle(100,10)

t.circle(300,30)

t.seth(0)

t.forward(230)

t.seth(90)

t.circle(300,30)

t.circle(100,3)

t.color((255,155,192),(255,100,100))

t.seth(-135)

t.circle(-80,63)

t.circle(-150,24)

t.end_fill()

# 手

t.color((255,155,192))

t.penup()

t.seth(90)

t.forward(-40)

t.seth(0)

t.forward(-27)

t.pendown()

t.seth(-160)

t.circle(300,15)

t.penup()

t.seth(90)

t.forward(15)

t.seth(0)

t.forward(0)

t.pendown()

t.seth(-10)

t.circle(-20,90)

t.penup()

t.seth(90)

t.forward(30)

t.seth(0)

t.forward(237)

t.pendown()

t.seth(-20)

t.circle(-300,15)

t.penup()

t.seth(90)

t.forward(20)

t.seth(0)

t.forward(0)

t.pendown()

t.seth(-170)

t.circle(20,90)

# 脚

t.pensize(10)

t.color((240,128,128))

t.penup()

t.seth(90)

t.forward(-75)

t.seth(0)

t.forward(-180)

t.pendown()

t.seth(-90)

t.forward(40)

t.seth(-180)

t.color("black")

t.pensize(15)

t.forward(20)

t.pensize(10)

t.color((240, 128, 128))

t.penup()

t.seth(90)

t.forward(40)

t.seth(0)

t.forward(90)

t.pendown()

t.seth(-90)

t.forward(40)

t.seth(-180)

t.color("black")

t.pensize(15)

t.forward(20)

# 尾巴

t.pensize(4)

t.color((255, 155, 192))

t.penup()

t.seth(90)

t.forward(70)

t.seth(0)

t.forward(95)

t.pendown()

t.seth(0)

t.circle(70, 20)

t.circle(10, 330)

t.circle(70, 30)

t.done()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值