Python画图小案例之小雪人超详细源码注释

作者:zhulin1028 时间:2021-09-21 11:49:44 

一步步教你怎么用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

标签:Python,雪人,Python,画图
0
投稿

猜你喜欢

  • 详解JavaScript中操作符和表达式

    2024-06-17 21:14:30
  • 详细解读tornado协程(coroutine)原理

    2022-08-21 00:20:18
  • 《用户体验的要素》摘记

    2008-08-04 17:59:00
  • 为什么相对PHP黑python的更少

    2024-05-21 10:20:51
  • 详解PANDAS 数据合并与重塑(join/merge篇)

    2022-12-13 04:02:08
  • 告别网页搜索!教你用python实现一款属于自己的翻译词典软件

    2023-08-08 17:46:58
  • 在 Golang 中实现 Cache::remember 方法详解

    2024-04-26 17:21:08
  • php官方微信接口大全(微信支付、微信红包、微信摇一摇、微信小店)

    2023-10-17 14:16:56
  • vuex管理状态仓库使用详解

    2024-04-30 10:38:33
  • 最新anaconda安装配置教程

    2021-07-17 05:05:34
  • Python异常对象Exception基础类异常捕捉

    2021-10-21 03:46:25
  • sql 常用技巧整理

    2011-11-03 17:10:14
  • 下拉列表两级连动的新方法(二)

    2009-06-04 18:22:00
  • 解决给dom元素绑定click等事件无效问题的方法

    2024-04-16 10:36:42
  • 数据仓库基本报表制作过程中的SQL写法

    2008-11-25 12:17:00
  • python操作mongodb根据_id查询数据的实现方法

    2023-04-04 23:12:28
  • 详解python时间模块中的datetime模块

    2023-09-26 02:41:28
  • 利用JavaScript实现拖拽改变元素大小

    2024-06-10 12:00:05
  • CSS框架的相关汇总(CSS Frameworks)

    2008-04-02 12:00:00
  • 详解AJAX核心 —— XMLHttpRequest 对象

    2010-03-31 14:49:00
  • asp之家 网络编程 m.aspxhome.com