Python画图小案例之小雪人超详细源码注释
作者:zhulin1028 发布时间:2021-09-21 11:49:44
标签:Python,雪人,Python,画图
一步步教你怎么用Python画雪人,进一步熟悉Python的基础画图操作,废话不多说,上代码。
希望您给个关注给个赞,也算对我们的支持了。
class Shape: # 基类(雪人各部件(形状)共有的属性)
def __init__(self, cvns, points, fill): # 构造方法 画布 位置坐标 颜色
self.cvns = cvns # 画布
self.points = points # 坐标(x1, y1, x2, y2)
self.fill = fill
self.pid = None # 当前图形的id
def delete(self): # 删除图形
if self.pid:
self.cvns.delete(self.pid)
class ShapeAngles(Shape): # 继承基类(增加了角度))
def __init__(self, cvns, points, fill, angles=(10, 170)): # angles:角度值,带默认参数
super(ShapeAngles, self).__init__(cvns, points, fill) # 调用基类构造: cvns,points,fill
self.angles = {'start':angles[0], 'extent':angles[1]} # 构造自己的属性:angles
class HatTop(Shape): # 帽子顶部
def draw(self):
# self.pid = self.cvns.create_oval(self.points, fill='white') # 椭圆形
self.pid = self.cvns.create_oval(self.points, fill=self.fill) # 椭圆形
class HatBottom(Shape): # 帽子底部
def draw(self):
self.pid = self.cvns.create_polygon(self.points) # 绘多边形的方法
class Hat: # 帽子整体(组合顶部和底部)
def __init__(self, cvns, start_point, fill, w, h): # w,h是帽子的宽、高
self.cvns = cvns # 初始化
self.start_point = start_point
self.w = w
self.fill = fill
self.h = h
self.ht = HatTop(self.cvns, self.ht_cacu(), fill=self.fill) # 实例化顶部
self.hb = HatBottom(self.cvns, self.hb_cacu(), self.fill) # 实例化底部
def draw(self): # 绘制
self.ht.draw() # 调用顶部方法绘制
self.hb.draw() # 调用底部方法绘制
def delete(self):
self.ht.delete()
# self.hb.delete()
def ht_cacu(self): # 计算顶部坐标
r = self.h / 3 / 2
x1 = self.start_point[0] + self.w / 2 - r
y1 = self.start_point[1] + 20 - r
x2 = x1 + 2 * r
y2 = y1 + 2 * r
return x1, y1, x2, y2
def hb_cacu(self): # 计算底部坐标(三角形的三个点的坐标)
x1 = self.start_point[0] + self.w / 2
y1 = self.start_point[1] + self.h / 3
x2 = self.start_point[0] + self.w / 3
y2 = self.start_point[1] + self.h + 13
x3 = self.start_point[0] + self.w / 3 * 2
y3 = y2
return x1, y1, x2, y2, x3, y3
class Sense(ShapeAngles): # 五官(眼、口扇形图形)
def draw(self):
self.pid = self.cvns.create_arc(*self.points, **self.angles, fill='red') # 绘制弧线
class Face(HatTop): # 脸
pass
class Head: # 头部
def __init__(self, cvns, start_point, fill, w, h): # 此处的w,h是头的
self.cvns = cvns
self.start_point = start_point
self.fill = fill
self.w = w
self.h = h
eye0_points = self.eye0_cacu() # 眼睛1坐标
dx = self.h / 3 + self.h / 9
eye1_points = (eye0_points[0] + dx, eye0_points[1], # 眼睛2坐标
eye0_points[2] + dx, eye0_points[3])
self.face = Face(self.cvns, self.face_cacu(), self.fill) # 脸:带参数的实例
self.eye0 = Sense(self.cvns, eye0_points, fill='blue') # 眼1:带参数的实例
self.eye1 = Sense(self.cvns, eye1_points, self.fill) # 眼2:带参数的实例
self.mouth = Sense(self.cvns, self.mouth_cacu(), (-10, -170)) # 口:带参数的实例
def draw(self):
# 绘制脸部各部位
self.face.draw()
self.eye0.draw()
self.eye1.draw()
self.mouth.draw()
def face_cacu(self): # 脸坐标计算
x1 = self.start_point[0] + (self.w - self.h) / 2
y1 = self.start_point[1]
x2 = x1 + self.h
y2 = y1 + self.h
return x1, y1, x2, y2
def eye0_cacu(self): # 眼0坐标计算
left_point = (self.start_point[0] + (self.w - self.h) / 2 - 5, self.start_point[1])
x1 = left_point[0] + self.h / 6
y1 = left_point[1] + self.h / 3
x2 = x1 + self.h / 3
y2 = left_point[1] + self.h / 2
return x1, y1, x2, y2
def mouth_cacu(self): # 口坐标计算
left_point = (self.start_point[0] + (self.w - self.h) / 2, self.start_point[1])
x1 = left_point[0] + self.h / 3
y1 = left_point[1] + 2 * self.h / 3 + 25 # +25后口的位置靠下,并且图形更大了
x2 = x1 + self.h / 3
y2 = left_point[1] + self.h / 2
return x1, y1, x2, y2
class hand(HatTop): # 手
pass
class BodyOutline(HatTop): # 身体轮廓,因没有特别的形状,继承了基类,类体为空
pass
class Button(HatTop): # 钮扣
pass
class Body: # 身体
def __init__(self, cvns, start_point, fill, w, h):
self.cvns = cvns
self.start_point = start_point
self.w = w
self.h = h
self.fill = fill
self._button_size = 10 # 钮扣的大小
self.buttons = []
self.bo = BodyOutline(self.cvns, self.body_cacu(), self.fill) # 身体轮廓实例
# self.hd = hand(self.cvns, (15, 500, 45, 240), self.fill) # 左手轮廓实例,坐标为矩形的两个对角顶点的坐标为准画的圆/椭圆
self.hd = hand(self.cvns, self.bd_cacu(0), self.fill) # 左手轮廓实例,坐标为矩形的两个对角顶点的坐标为准画的圆/椭圆
self.hd2 = hand(self.cvns, self.bd_cacu(self.w), self.fill) # 右手
for pnts in self.all_button_points():
self.buttons.append(Button(self.cvns, pnts, self.fill))
def bd_cacu(self, w): # 计算手的坐标
x1 = 15 + w
y1 = self.start_point[1] + self.h / 2
x2 = x1 + 30
y2 = y1 - 26 * self._button_size
return x1, y1, x2, y2
def draw(self):
self.bo.draw() # 身体绘制
self.hd.draw() # 手1绘制
self.hd2.draw() # 手2绘制
for bttn in self.buttons: # 各钮扣绘制
bttn.draw()
def body_cacu(self): # 计算身体轮廓坐标
x1, y1 = self.start_point
x2 = x1 + self.w
y2 = y1 + self.h
return x1, y1, x2, y2
def button0_cacu(self): # 计算第0个钮扣的坐标
x1 = self.start_point[0] + self.w / 2 - self._button_size
y1 = self.start_point[1] + self.h / 5 - self._button_size
x2 = x1 + 2 * self._button_size # 2决定钮扣的园形形状
y2 = y1 + 2 * self._button_size
return x1, y1, x2, y2
def move_dy(self, points, size): # 钮扣移动的方法
y1 = points[1] + size
y2 = points[3] + size
return points[0], y1, points[2], y2
def all_button_points(self): # 绘制每个钮扣的坐标
b0_points = self.button0_cacu()
size = self.h / 6 # 身高/钮扣数+1
points = [] # 列表
for i in range(5): # 钮扣的个数
points.append(self.move_dy(b0_points, i * size)) # 各钮扣的移动数据存入列表points
return points # 返回列表值
# def set_button_size(self, size):
# self._button_size = size
class Snow: # 组装成雪人
def __init__(self, cvns, points, fill, w=150, h=450): # points为雪人的坐标其与帽子坐标一致(见雪人图)
self.cvns = cvns
self.points = points
self.w = w
self.h = h
self.fill = fill
self.head = Head(self.cvns, (self.points[0], self.points[1] + self.h / 6), self.fill, self.w, self.h / 3) # 实例化头部
self.body = Body(self.cvns, (self.points[0], self.points[1] + self.h / 2), self.fill, self.w, self.h / 2) # 实例化身体
self.fill = 'red' # 帽子顶部颜色
self.hat = Hat(self.cvns, self.points, self.fill, self.w, self.h / 6) # 绘帽子 # 实例化帽子
def draw(self):
self.hat.draw() # 绘制帽子
self.head.draw() # 绘制头
self.body.draw() # 绘制身体
if __name__ == '__main__':
import tkinter
root = tkinter.Tk() # 建立根窗口
cvns = tkinter.Canvas(root, width=400, height=700, bg='white') # 调用画布
cvns.pack() # 将画布添加到窗口
snow = Snow(cvns, (30, 15), 'white', 320, 660) # 雪人的实例化(传入画布对象、起始坐标、宽、高)
snow = snow.draw() # 绘制
root.mainloop()
来源:https://blog.csdn.net/xiejiachao/article/details/120536554
0
投稿
猜你喜欢
- 本篇主要将react全家桶的产品非常精炼的提取了核心内容,精华程度堪比精油。各位大人,既然来了,客官您坐,来人,给客官看茶~~redux前言
- 1.锦短情长为什么选择这个标题,借鉴了一封情书里面的情长纸短,还吻你万千。锦短情长都只谓人走茶凉,怎感觉锦短情长?一提起眼泪汪汪,是明月人心
- 总经一下前段时间用于的jQuery方法:find及children。需要的朋友可以参考下。首先看看英文解释吧: children方法:fin
- 项目中需要FusionCharts图表显示双Y轴,好像FCF_MSLine.swf不可以这样,只能显示一个Y轴,多条线, 找了一下,用MSC
- 今天继续给大家介绍Python相关知识,本文主要内容是Python asyncio异步编程常见问题。一、asyncio编程简单示例首先,我们
- 地址:https://youzan.github.io/vant/#/zh-CN/intro一.引入Vant组件库1.首先运行 npm in
- 也许已经有人发现可以这样写...CSS代码部分a.info { position:
- 编写 models.py 文件from django.db import models# Create your models here.c
- 设计思路本文整理归纳以往的工作中用到的东西,现汇总成基础测试框架提供分享。框架采用python3 + selenium3 + PO + ya
- 一个完整的域名,由根域、顶级域、二级、 * ……域名构成,每级域名之间用点分开,每级域名由字母、数字和减号构成(第一个字母不能是减号),不区分
- ADB是Android SDK中的一个工具, 使用ADB可以直接操作管理Android模拟器或者真实的Andriod设备。ADB主要功能有:
- 搞不清楚在闭包(closures)中Python是怎样绑定变量的看这个例子:>>> def create_multipli
- uni-simple-router专为uniapp打造的路由器,和uniapp深度集成通配小程序、App和H5端H5能完全使用vue-rou
- 解析html是爬虫后的重要的一个处理数据的环节。一下记录解析html的几种方式。先介绍基础的辅助函数,主要用于获取html并输入解析后的结束
- 先问一个问题, 在firefox 2里,正则表达式字符"\d"全等于"[0-9]"吗?有可能你会答&
- 作为一名前端,我们通常要做的就是让页面在各系统A-Grade浏览器,甚至网站浏览份额0.1%以上的浏览器上良好显示。当然,还有性能问题。不过
- access中可以将文本中的数据轻松导入表中,mysql中用起来没那么方便,其实起来也很简单。首先将数据记录按行处理好用特定的字符分开如:“
- 经常在网上冲浪的朋友是否曾注意到有些网站的鼠标不是规则的斜向上箭头的形状,而是"十"
- 公式首先需要了解CrossEntropyLoss的计算过程,交叉熵的函数是这样的:其中,其中yi表示真实的分类结果。这里只给出公式,关于Cr
- 继续Mootools常用方法扩展,依然还是String类的扩展。方法:format说明:一个非常简单的format方法,和C#