ESP-IDF Micro python学习笔记3 | 构建对象及子对象

 一、准备

1、创建一个lvdiv.c文件 

 在创建新的文件的同时,要在CMakeLists.txt里加入文件名

二、构建对象

1、 定义类型的字典

STATIC const mp_rom_map_elem_t lv_div_locals_dict_table[] ={}

2、把字典转换成对象

STATIC MP_DEFINE_CONST_DICT(lv_div_locals_dict, lv_div_locals_dict_table);

3、定义类结构

const mp_obj_type_t lv_type_div = {
    { &mp_type_type},               // 必须以这个开头
    .name = MP_QSTR_div,            // 类的名字(注意大小写)
    .locals_dict = (mp_obj_dict_t *)&lv_div_locals_dict, // 添加类成员字典
    .make_new = lv_div_make_new,    // 构造函数
};

4、构造函数

STATIC mp_obj_t lv_div_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args){
    // 检查参数数量是否正确
    mp_arg_check_num(n_args, n_kw, 0, 1, false);

    // 开始构造对象
    lv_div_t *self = m_new_obj(lv_div_t);                           // *
    self->base.type = &lv_type_div;         // 必须设置返回值的类型            // *

    // 父级对象
    if(n_args>0 && mp_obj_get_type(args[0]) == &lv_type_div){
        printf("确认是父级\n");
        self->parent = (lv_div_t *)args[0];
    }

    return MP_OBJ_FROM_PTR(self);                                   // *
}

5、在 lv_mod.h 里定义数据类型

// 定义DIV结构体
struct _lv_div_t{
    mp_obj_base_t base;         // 每个 Micropython 类必须以这个开始
    int16_t x;
    int16_t y;
    uint32_t width;
    uint32_t height;
    lv_div_t *parent;
};

6、构建成员方法


// 1. 分别获得 x,y , width ,height
// 2. positon, size
// 3. box(x, y, w, h)

// STATIC mp_obj_t lv_div_px(mp_obj_t self_in, mp_obj_t value){
// MP_DEFINE_CONST_FUN_OBJ_2
STATIC mp_obj_t lv_div_px(size_t n_args, const mp_obj_t *args){
    lv_div_t *self = (lv_div_t *)args[0];
    if(n_args>1 && &mp_type_int == mp_obj_get_type(args[1])){
        // 赋值
        self->x = mp_obj_get_int(args[1]);
    }
    return mp_obj_new_int(self->x);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(lv_div_px_obj,1,2,lv_div_px);


STATIC mp_obj_t lv_div_py(size_t n_args, const mp_obj_t *args){
    mp_arg_check_num(n_args,0,1,2,false);
    lv_div_t *self = (lv_div_t *)args[0];
    if(n_args>1 && &mp_type_int == mp_obj_get_type(args[1])){
        // 赋值
        self->y = mp_obj_get_int(args[1]);
    }
    return mp_obj_new_int(self->y);
}
MP_DEFINE_CONST_FUN_OBJ_VAR(lv_div_py_obj,1,lv_div_py);

/**
 * @brief 设置位置
 * 传入两个或者一个参数表设置,不传参表示获取
 * (x, y)
 * (x)
 * ((x,y))
 * ([x,y])
 * () =>(x,y)
*/
STATIC mp_obj_t lv_div_position(size_t n_args, const mp_obj_t *args){
    lv_div_t *self = (lv_div_t *)args[0];
    if(n_args>1){
        // 设置
        // 1 个int
        // 2 个 int
        // 1 元组
        if(2 == n_args ){        // 表示传入一个参数
            if(&mp_type_int == mp_obj_get_type(args[1])){   // 只设置 x
                self->x = mp_obj_get_int(args[1]);
            }else if(&mp_type_tuple == mp_obj_get_type(args[1])){
                mp_obj_tuple_t *t = args[1];
                if(t->len==1){ // 只传入了一个值
                    self->x = mp_obj_get_int(t->items[0]);
                }else if(t->len>1){
                    self->x = mp_obj_get_int(t->items[0]);
                    self->y = mp_obj_get_int(t->items[1]);
                }
            }
        }else if(n_args>2){
            if(&mp_type_int == mp_obj_get_type(args[1]) && &mp_type_int == mp_obj_get_type(args[2])){
                self->x = mp_obj_get_int(args[1]);
                self->y = mp_obj_get_int(args[2]);
            }
        }
        return MP_OBJ_FROM_PTR(self);
    }else{
        mp_obj_t pos_table[2];                                  // 创造元组都数组
        pos_table[0] = mp_obj_new_int(self->x);                 // 设置元组元素
        pos_table[1] = mp_obj_new_int(self->y);
        mp_obj_tuple_t *pos = mp_obj_new_tuple(2,pos_table);    // 创造一个元组

        return MP_OBJ_FROM_PTR(pos);
    }
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(lv_div_position_obj,1,3,lv_div_position);

STATIC mp_obj_t lv_div_size(size_t n_args, const mp_obj_t *args){
    lv_div_t *self = (lv_div_t *)args[0];
    if(n_args>1){   // 设置
        // 设置
        // 1 个int
        // 2 个 int
        // 1 元组
        if(2 == n_args ){        // 表示传入一个参数
            if(&mp_type_int == mp_obj_get_type(args[1])){   // 只设置 x
                self->width = mp_obj_get_int(args[1]);
            }else if(&mp_type_tuple == mp_obj_get_type(args[1])){
                mp_obj_tuple_t *t = args[1];
                if(t->len==1){ // 只传入了一个值
                    self->width = mp_obj_get_int(t->items[0]);
                }else if(t->len>1){
                    self->width = mp_obj_get_int(t->items[0]);
                    self->height = mp_obj_get_int(t->items[1]);
                }
            }
        }else if(n_args>2){
            if(&mp_type_int == mp_obj_get_type(args[1]) && &mp_type_int == mp_obj_get_type(args[2])){
                self->width = mp_obj_get_int(args[1]);
                self->height = mp_obj_get_int(args[2]);
            }
        }
        return MP_OBJ_FROM_PTR(self);
    }else{
        mp_obj_t pos_table[2];                                  // 创造元组都数组
        pos_table[0] = mp_obj_new_int(self->width);             // 设置元组元素
        pos_table[1] = mp_obj_new_int(self->height);
        mp_obj_tuple_t *pos = mp_obj_new_tuple(2,pos_table);    // 创造一个元组

        return MP_OBJ_FROM_PTR(pos);
    }
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(lv_div_size_obj,1,3,lv_div_size);

 并将成员方法加入到字典里

STATIC const mp_rom_map_elem_t lv_div_locals_dict_table[] ={
    { MP_ROM_QSTR(MP_QSTR_DEFAULT_WIDTH), MP_ROM_INT(200)},
    { MP_ROM_QSTR(MP_QSTR_px), MP_ROM_PTR(&lv_div_px_obj)},
    { MP_ROM_QSTR(MP_QSTR_py), MP_ROM_PTR(&lv_div_py_obj)},
    { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&lv_div_position_obj)},
    { MP_ROM_QSTR(MP_QSTR_sizet), MP_ROM_PTR(&lv_div_size_obj)},
};

三、构建对象的子对象

1、新建一个 lvspan.c 的文件

并在 CMakeLists.txt 里加上新建的文件名

2、 定义子类型的字典

STATIC const mp_rom_map_elem_t lv_span_locals_dict_table[]={};

3、将字典转换成对象

STATIC MP_DEFINE_CONST_DICT(lv_span_locals_dict, lv_span_locals_dict_table);

4、定义子类的结构

const mp_obj_type_t lv_type_span = {
    { &mp_type_type},               // 必须以这个开头
    .name = MP_QSTR_span,            // 类的名字(注意大小写)
    .locals_dict = (mp_obj_dict_t *)&lv_span_locals_dict, // 添加类成员字典
    .make_new = lv_span_make_new,    // 构造函数
    .attr = call_parent_methods,        // 暴露父类方法
    .parent = &lv_type_div,
};

 .attr = call_parent_methods,        // 暴露父类方法

可以调用父类的成员方法:


void call_parent_methods(mp_obj_t obj, qstr attr, mp_obj_t *dest)
{
    const mp_obj_type_t *type = mp_obj_get_type(obj);
    while (type->locals_dict != NULL) {
        // generic method lookup
        // this is a lookup in the object (ie not class or type)
        assert(type->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now
        mp_map_t *locals_map = &type->locals_dict->map;
        mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
        if (elem != NULL) {
            mp_convert_member_lookup(obj, type, elem->value, dest);
            break;
        }
        if (type->parent == NULL) {
            break;
        }
        // search parents 
        type = type->parent;
    }
}

.parent = &lv_type_div :将 lvdiv 作为 lvspand 的父类

4、构建函数

STATIC mp_obj_t lv_span_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args){
    lv_span_t *self = m_new_obj(lv_span_t);
    self->base.base.type = type;
    // 父级对象
    if(n_args>0 && mp_obj_get_type(args[0]) == &lv_type_div){
        printf("确认是父级\n");
        self->base.parent = (lv_div_t *)args[0];
    }
    return MP_OBJ_FROM_PTR(self);
}

5、在 lv_mod.h 里定义数据类型

// 继承自 DIV 的类
struct _lv_span_t{
    lv_div_t base;
    uint32_t color;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值