麦子学院——Python面向对象编程(P14通过组合来构建复杂对象)

这篇博客主要讲解如何使用Python的面向对象编程来构建复杂对象,包括雪人的移动和部件颜色修改功能的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

1、修改本实例程序,添加让雪人整体移动的功能。
2、修改本程序,添加修改雪人帽子和纽扣颜色的功能

答案

class Shape:
    def __init__(self, cvns, points):
        self.cvns = cvns
        self.points = points
        self.pid = None

    def delete(self):
        if self.pid:
            self.cvns.delete(self.pid)

class ShapeAngles(Shape):
    def __init__(self, cvns, points, angles=(10, 170)):     # ShapeAngles类只比Shape类多出一个angles属性
        super().__init__(cvns, points)
        self.angles = {"start": angles[0], "extent": angles[1]}

class HatTop(Shape):
    def draw(self):
        self.pid = self.cvns.create_oval(*self.points)      # *代表self.points为元组数据

    def move(self):
        self.cvns.move(self.pid, 10, 0)      # 每次点击向右移动10单位

    def changeColor(self):          # 将颜色变为蓝色
        self.delete()
        self.pid = self.cvns.create_oval(*self.points, fill="blue")

class HatBottom(Shape):
    def draw(self):
        self.pid = self.cvns.create_polygon(*self.points)

    def move(self):
        self.cvns.move(self.pid, 10, 0)          # 每次点击向右移动10单位

    def changeColor(self):              # 将颜色变为蓝色
        self.delete()
        self.pid = self.cvns.create_polygon(*self.points, fill="blue")


class Hat:
    def __init__(self, cvns, start_point, w, h):
        self.cvns = cvns
        self.start_point = start_point
        self.w = w
        self.h = h
        self.ht = HatTop(self.cvns, self.ht_cacu())
        self.hb = HatBottom(self.cvns, self.hb_cacu())

    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          # 帽子顶端圆的半径,圆的直径与三角形的高之比为1:2。
        x1 = self.start_point[0] + self.w / 2 - r  # (x1,y1)和(x2,y2)是圆的外切正方形的两个端点(西北点和东南点)
        y1 = self.start_point[1]
        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   # (x1,y1)为三角形上顶点
        y1 = self.start_point[1] + self.h / 3
        x2 = self.start_point[0] + self.w / 3   # (x2,y2)为三角形左顶点
        y2 = self.start_point[1] + self.h
        x3 = self.start_point[0] + self.w / 3 * 2       # (x3,y3)为三角形右顶点
        y3 = y2
        return x1, y1, x2, y2, x3, y3

    def move(self):
        self.ht.move()
        self.hb.move()

    def changeColor(self):
        self.ht.changeColor()
        self.hb.changeColor()

class Sense(ShapeAngles):
    def draw(self):
        self.pid = self.cvns.create_arc(*self.points, **self.angles)    # **代表self.angles为字典类型数据

    def move(self):     # 每次点击向右移动10单位
        self.cvns.move(self.pid, 10, 0)


class Face(HatTop):
    pass

class Head:
    def __init__(self, cvns, start_point, w, h):
        self.cvns = cvns
        self.start_point = start_point
        self.w = w
        self.h = h
        eye0_points = self.eye0_cacu()
        dx = self.h / 3 + self.h / 9
        eye1_points = (eye0_points[0] + dx, eye0_points[1], \
                       eye0_points[2] + dx, eye0_points[3])
        self.face = Face(self.cvns, self.face_cacu())
        self.eye0 = Sense(self.cvns, eye0_points)
        self.eye1 = Sense(self.cvns, eye1_points)
        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    # (x1,y1)为脸圆形的外切正方形的西北点
        y1 = self.start_point[1]
        x2 = x1 + self.h        # (x2,y2)为脸圆形的外切正方形的东南点
        y2 = y1 + self.h
        return x1, y1, x2, y2

    def eye0_cacu(self):
        left_point = (self.start_point[0] + (self.w - self.h) / 2, self.start_point[1])  # 脸圆形的外切正方形的西北点
        x1 = left_point[0] + self.h / 6     # (x1,y1)为眼圆形(弧形为部分圆形)的外切正方形的西北点
        y1 = left_point[1] +self.h / 3
        x2 = x1 + self.h / 3                # (x2,y2)为眼圆形的外切正方形的东南点
        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      # (x1,y1)为嘴圆形(弧形为部分圆形)的外切正方形的西北点
        y1 = left_point[1] + 2 * self.h / 3
        x2 = x1 + self.h / 3            # (x2,y2)为嘴圆形(弧形为部分圆形)的外切正方形的东南点
        y2 = y1 + self.h / 3 / 2
        return x1, y1, x2, y2

    def move(self):
        self.face.move()
        self.eye1.move()
        self.eye0.move()
        self.mouth.move()


class BodyOutline(HatTop):
    pass

class Button(HatTop):
    pass

class Body:
    def __init__(self, cvns, start_point, w, h):
        self.cvns = cvns
        self.start_point = start_point
        self.w = w
        self.h = h
        self._button_size = 10  # 纽扣圆的半径
        self.buttons = []
        self.bo = BodyOutline(self.cvns, self.body_cacu())
        for pnts in self.all_button_points():
            self.buttons.append(Button(self.cvns, pnts))

    def draw(self):
        self.bo.draw()
        for bttn in self.buttons:
            bttn.draw()

    def body_cacu(self):
        x1, y1 =self.start_point    # (x1,y1)为身体圆形的西北点
        x2 = x1 + self.w            # (x2,y2)为身体圆形的东南点
        y2 = y1 + self.h
        return x1, y1, x2, y2

    def button0_cacu(self):
        x1 = self.start_point[0] + self.w / 2 - self._button_size       # (x1,y1)为第一个纽扣圆的西北点
        y1 = self.start_point[1] + self.h / 5 - self._button_size
        x2 = x1 + 2 * self._button_size         # (x2,y2)为第一个纽扣圆的东南点
        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 / 5
        points = []
        for i in range(4):
            points.append(self.move_dy(b0_points, i * size))
        return points

    def set_button_size(self, size):
        self._button_size = size

    def move(self):
        self.bo.move()
        for bttn in self.buttons:
            bttn.move()

    def changeColor(self):
        for bttn in self.buttons:
            bttn.changeColor()

class Snow:
    def __init__(self, cvns, points, w=150, h=450):
        self.cvns = cvns
        self.points = points
        self.w = w
        self.h = h
        self.hat = Hat(self.cvns, self.points, self.w, self.h / 6)
        self.head = Head(self.cvns, (self.points[0], self.points[1] + self.h / 6), self.w, self.h / 3)  # self.h / 3?
        self.body = Body(self.cvns, (self.points[0], self.points[1] + self.h / 2), self.w, self.h / 2)

    def draw(self):
        self.hat.draw()
        self.head.draw()
        self.body.draw()

    def move(self):
        self.hat.move()
        self.head.move()
        self.body.move()

    def changeColor(self):
        self.hat.changeColor()
        self.body.changeColor()

测试

if __name__ == "__main__":
    import tkinter
    root = tkinter.Tk()
    cvns = tkinter.Canvas(root, width=600, height=550, bg="white")
    cvns.pack()
    snow = Snow(cvns, (10, 5), 200, 450)        # 让雪人缩小一点
    snow.draw()

    def snow_move():    # 定义一个移动函数,将其作为command的实参
        snow.move()

    def change_color():     # 定义一个变颜色函数,将其作为command的实参
        snow.changeColor()

    frm = tkinter.Frame(root)
    frm.pack()
    sub_frm = tkinter.Frame(frm)
    sub_frm.pack(side="bottom")
    Butt1 = tkinter.Button(sub_frm, text="move", command=snow_move).grid(row=0, column=0)
    Butt2 = tkinter.Button(sub_frm, text="change color", command=change_color).grid(row=0, column=1)
    root.mainloop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值