ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Python turtle绘制贺卡:从画布坐标系到完整实例代码

2026/9/16 13:53:56 拓冰建站 浏览量
Python turtle绘制贺卡:从画布坐标系到完整实例代码 简介面向Python初学者与编程爱好者这是一份电子贺卡制作项目的实例源码。代码借助Tkinter图形界面、Pillow图像处理和声音集成实现祝福语输入、样式选择、背景图片与动态效果等功能覆盖Python基础语法、GUI编程、文件操作、事件处理、动画与音效等知识点适合在趣味项目中巩固编程基础。压缩包共9个文件包含6张png背景图片、1个py主程序、1个ttf字体文件及1个requirements说明文件整体约5.41MB目录简洁便于直接运行与二次修改。目前已有67人学习下载。借助该实例读者可以掌握从界面搭建到资源打包的完整流程理解如何在实用小工具中灵活运用Python常用库提升实际编码与排错能力。1. 贺卡这个例子Python新手练完能带走什么收到“Python实例源码-实例17-贺卡”这个项目通常不会只是让你打印一行“Happy Birthday”字符。多数入门教材把这个编号排在面向过程语法之后、面向对象之前用意很明确用一份看得见、摸得着的图形输出把变量、循环、函数调用、坐标计算一次串起来。贺卡比计算器、猜数字更有反馈感——运行完屏幕上铺开一张带文字、配色和装饰的卡片这种即时视觉反馈能帮你确认“这段代码到底控制住了什么东西”。这个项目适合两类人一类是刚学完基础语法、想找不枯燥练手程序的新手另一类是带学生的讲师需要一个能改参数、能扩展、能演示代码复用的小案例。我会用 Python 标准库里的turtle模块来落这个贺卡——不依赖第三方包python 环境只要装了解释器就能跑。整个例子会从画布坐标讲起落到完整成品代码再给到字体、配色、动效和导出的小技巧。2. 画布坐标系与画笔模型不搞懂 turtle 的定位贺卡会画歪turtle是 Python 内置的绘图库模拟一支可以在画布上移动的画笔。它最容易被忽略、也最容易让贺卡翻车的点不是命令记不住而是坐标系没建立起来。turtle的默认画布是 800×600 像素坐标原点(0, 0)在画布正中心x 轴向右增大y 轴向上增大。很多新手第一反应是“左上角应该是 (0, 0)”于是画出来的内容直接偏到画面外。2.1 先跑通最小窗口确认环境与版本如果你还在准备 python 环境请先确认解释器已正确安装。在终端或命令提示符下执行python --version能打印出版本号继续往下走。如果你用 VS Code 写代码建议先给当前文件选好解释器打开命令面板CtrlShiftP输入 “Python: Select Interpreter”选一个能用的 python 环境。这一步不做跑代码时可能报“python was not found”或者导入模块失败。然后写一个最简启动文件import turtle t turtle.Turtle() t.speed(3) t.forward(100) turtle.done()turtle.Turtle()创建画笔对象speed(3)把绘制速度设定在中间档位forward(100)让画笔前进 100 像素turtle.done()保持窗口不自动关闭。如果这段能画出一条线说明基础链路没问题。注意done()必须写在最后很多新手在循环里误用done()导致窗口提前卡死实际上它是事件循环的入口不是每画一笔调一次的函数。2.2 画笔状态与坐标换算参数在变画笔在走心里得有数turtle画笔的状态由三样东西组成位置、朝向、是否落笔。位置是一个二维坐标点朝向是当前画笔与 x 轴正方向的夹角单位是度落笔与否决定移动时是否留下轨迹。你要做贺卡本质上是在预先把每个元素的中心坐标算好然后指挥画笔到达指定点再旋转到指定角度最后画线或填充色块。turtle提供的坐标系命令包括命令作用典型参数goto(x, y)移动到绝对坐标goto(-100, 50)setx/sety只改变当前 x 或 ysetx(200)home()回到原点并朝右无参数setheading(angle)设置朝向setheading(90)朝上left/right(angle)相对转角度left(45)penup/pendown抬笔/落笔无参数pensize(width)设置线宽pensize(3)color(pencolor, fillcolor)设置画笔色和填充色color(red, pink)做贺卡时我习惯先把所有元素按虚拟坐标网格规划好背景占满整张画布贺词放在偏上三分之一的位置装饰图案围绕文字四周分布。坐标不用太精确但方向感要明确——turtle的left(90)是逆时针转画圆时circle(半径, 角度)正角度逆时针画弧负角度顺时针画弧。这些方向规则和数学课本坐标系一致不用额外记。一个常见误区是频繁使用abs或复杂条件判断去修正画笔位置。实际上penup()后goto()再pendown()才是标准做法。移动时不画线定位到新点后落笔干净利落。3. 贺卡核心代码从背景到贺词的一步步分层实现这个实例的目标是生成一张静止的节日贺卡主体结构分四层背景、装饰边框、主体图案、文字。3.1 完整代码先把能跑通的版本拿到手import turtle def draw_bg(): t turtle.Turtle() t.speed(0) t.penup() t.goto(-400, -300) t.pendown() t.color(#fdf6e3) t.begin_fill() for _ in range(2): t.forward(800) t.left(90) t.forward(600) t.left(90) t.end_fill() t.hideturtle() def draw_border(): t turtle.Turtle() t.penup() t.goto(-350, 250) t.pendown() t.color(#b58900) t.pensize(4) for _ in range(2): t.forward(700) t.right(90) t.forward(500) t.right(90) t.hideturtle() def draw_text(): t turtle.Turtle() t.penup() t.goto(0, 120) t.color(#cb4b16) t.write(Happy Birthday, aligncenter, font(Arial, 40, bold)) t.goto(0, 50) t.write(To You!, aligncenter, font(Arial, 28, normal)) t.hideturtle() def draw_lights(): t turtle.Turtle() t.speed(6) colors [#dc322f, #268bd2, #859900, #d33682, #6c71c4] positions [(-250, -180), (-120, -220), (0, -200), (130, -225), (250, -180)] for pos, col in zip(positions, colors): t.penup() t.goto(pos[0], pos[1]) t.pendown() t.color(col) t.begin_fill() t.circle(18) t.end_fill() t.hideturtle() def main(): draw_bg() draw_border() draw_text() draw_lights() turtle.done() if __name__ __main__: main()代码逻辑是自底向上逐层绘制draw_bg()铺整张画布背景遍历两次“前进转向”画一个矩形并用begin_fill()/end_fill()填充draw_border()从(-350, 250)出发向外画边框draw_text()使用write()在指定坐标输出字符串aligncenter表示文字以该坐标为水平中心draw_lights()在卡片底部画一圈彩球每个彩球的坐标和颜色由列表给出。draw_bg()中speed(0)表示最快速度绘制适合先铺底色draw_lights()用speed(6)既能看清轨迹也不至于等太久。hideturtle()在每层绘制完成后隐藏画笔避免成品里出现一个三角箭头。3.2 参数怎么改动几个数卡片就变成另一种风格这个贺卡实例的参数调整集中在三个位置位置坐标、颜色值、字体参数。位置坐标影响整体布局。比如把draw_text()的 y 坐标从120改成80文字整体下移给上方留出画气球或烟花的空间。把positions列表里的 y 坐标从-180改到-250底部彩球更贴近卡片下边缘。我一般会先运行一遍观察元素间距再按 20 像素为单位微调。颜色值使用十六进制是最灵活的。turtle的color()支持颜色名字符串如red和#rrggbb格式。建议配色时使用同一套色系的十六进制值例如背景#fdf6e3暖米色、边框#b58900暗金色、文字#cb4b16橙红色、装饰#dc322f红色这种组合整体有节日感同时不刺眼。如果你想要更活泼的风格把背景换成#fff0f5淡紫红边框换成#ff69b4再配#333333的文字也能形成协调效果。字体参数方面font(Arial, 40, bold)是元组结构顺序为字体名、字号、样式。中文字体在不同系统上有差异Windows 上可用SimHei或Microsoft YaHeimacOS 上可用PingFang SC。Linux 系统上如果中文字体缺失运行时会看到方块字此时改用英文字符串最稳妥。t.write(生日快乐, aligncenter, font(SimHei, 36, bold))3.3 绘制顺序的影响先画什么后画什么结果完全不同贺卡绘制有明确的层叠关系后画的元素覆盖先画的元素。所以正确的顺序是“背景 → 大色块装饰 → 文字 → 细节点缀”。如果你把文字放最底层背景就会直接盖住文字如果把细节装饰放在背景之前装饰会被背景填充色遮掉。draw_bg()里填充背景使用的是“先 goto 到左下角然后 forward 和 left 交替两次”的方式。这种方式比直接调用turtle.bgcolor()更可控——bgcolor()设置的是窗口底色导出图片时有些环境无法把窗口底色一并保存而手动绘制并填充背景矩形导出的截图内容是完整的一张卡片。这也是处理贺卡导出问题时的一个小技巧后面第 5 章会展开讲。4. 丰富卡片层次文字、星点、动效与个性签名的扩展一张合格的贺卡不能只有边框和一行字。实例17 的进阶方向是把贺卡变成“有设计感”的成品。常见做法是在主体代码上叠加四类扩展文本装饰、随机星点、动态绘制、署名区。4.1 文字装饰双层描边与换行控制write()方法不支持多行文本自动换行你需要分别调用。双层描边的做法是先在(0, 120)用粗体大字写一遍深色文字再在(0, 118)用浅色小字覆盖视觉上形成“描边”效果。实际代码中可以让 y 轴偏移 2~3 个像素# 文字阴影层 t.goto(0, 122) t.color(#073642) t.write(Happy Birthday, aligncenter, font(Arial, 40, bold)) # 文字主层 t.goto(0, 120) t.color(#cb4b16) t.write(Happy Birthday, aligncenter, font(Arial, 40, bold))4.2 随机星点背景别让卡片留白太空用random模块生成随机位置的圆形光点能快速提升卡片精致度。注意控制随机范围不要让星点覆盖文字区域。import random def draw_stars(count30): t turtle.Turtle() t.speed(0) t.penup() for _ in range(count): x random.randint(-380, 380) y random.randint(-280, 260) if -180 x 180 and -80 y 160: continue t.goto(x, y) t.pendown() t.color(#fdf6e3) t.begin_fill() t.circle(random.randint(1, 3)) t.end_fill() t.penup() t.hideturtle()continue在这里跳过文字区域内部的位置保证星星只出现在四周。这个“排除核心区域”的思路在做各种随机点缀时都通用。4.3 动态效果用循环与time.sleep模拟手写过程turtle自带延迟刷新的特性配合speed()和循环就能模拟出手写文字或逐笔绘制的过程。常见做法是将绘制拆成若干段每段之间加入短暂停import time def draw_decorate_loop(): t turtle.Turtle() t.speed(3) for i in range(5): t.penup() t.goto(-100 i * 30, -280) t.pendown() t.color(#b58900) t.dot(8) time.sleep(0.3) t.hideturtle()dot(size)画实心圆点比circle()少写两行填充代码。sleep(0.3)让每个点之间停顿 0.3 秒看起来像逐一点亮。如果你是做教学演示这个动效足够直观。4.4 签名区给贺卡收个尾在卡片右下角放一个落款是贺卡项目的惯例。write()本身不支持斜体但可以通过font(Arial, 14, italic)在支持斜体的字体上实现。t.penup() t.goto(250, -250) t.color(#586e75) t.write(From Python, alignright, font(Arial, 14, italic))4.5 更多实例思路从贺卡到手绘图案生成器贺卡做完之后顺势扩展成“图案生成器”会让这个实例的输出价值更高。把draw_lights()中的positions和colors合并成语料数据从一个元组列表里读取位置与颜色再通过参数控制数量、半径和配色方案就能复用到雪花、气球、圣诞树装饰等场景。这个思路是“数据与绘制逻辑分离”的最初形态也是turtle案例中比较少见的架构升级。5. 导出与检查把 turtle 窗口变成这张贺卡最终交付的图片代码能跑出窗口只是第一步贺卡最终往往要发给别人或放进文档需要导出成 PNG / JPG 图片。turtle本身没有直接的savefig()但有两种可靠路径。5.1 方法一内置矢量格式转 PNG推荐macOS 和 Linux 上turtle生成的画布可以通过其底层tkinter.Canvas拿到 PostScript 数据import turtle # 在所有绘制完成、turtle.done() 之前调用 canvas turtle.getcanvas() canvas.postscript(filecard.eps, width800, height600)生成的.eps是矢量图再用 Pillow 转成普通图片格式pip install pillowfrom PIL import Image img Image.open(card.eps) img.save(card.png)需要留意的是EPS 转 PNG 时颜色和字体可能会有些许偏差尤其在中文字体渲染上。如果转换结果里中文字体变方块检查系统是否安装了对应字体或改用英文文本。5.2 方法二直接截屏Windows 上的稳妥方案Windows 下 EPS 转 PNG 的成功率不稳定最常见的做法是截屏运行完代码后按AltPrintScreen截取当前活动窗口再粘贴到画图或直接保存。这个方法不需要额外库缺点是截屏带窗口边框。还想再省事一点可以在代码最后加上窗口定位逻辑然后把画布置于屏幕固定位置turtle.getscreen().getcanvas().winfo_rootx()不过这个 API 在不同系统上表现不一致教学场景用自动截屏反而增加额外问题不如手动按一下键盘来得快。5.3 常见运行问题速查现象原因解法运行后窗口闪退缺turtle.done()在最后补上turtle.done()画笔线宽设置无效画笔宽度必须在画线之前设置在pendown()之前或之后立刻pensize()填充色不对调用了begin_fill()但结束前画笔没闭合回路确认填充图形是一个封闭路径中文字体变方块系统无对应字体换字体名或改用英文文字位置偏离中心alignright被误用检查align参数是left,center还是right最后一个小技巧问自己“这张贺卡上哪个元素最不好调”。我通常把positions和colors这两个列表抽出来放在代码文件顶部做成配置区这样改布局时不需要翻函数实现。把数据从逻辑里拆出来是这个实例源码里最值得带走的一个习惯。本文还有配套的精品资源点击获取