脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - Python画图小案例之小雪人超详细源码注释

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

2022-01-17 10:32zhulin1028 Python

在看了很多Python教程之后,觉得是时候做点什么小项目来练练手了,于是想来想去,用python写了一个小雪人,代码注释无比详细清楚,快来看看吧

一步步教你怎么用Python画雪人,进一步熟悉Python的基础画图操作,废话不多说,上代码。

希望您给个关注给个赞,也算对我们的支持了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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()

到此这篇关于Python画图小案例之小雪人超详细源码注释的文章就介绍到这了,更多相关Python 雪人 内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/xiejiachao/article/details/120536554

延伸 · 阅读

精彩推荐