lvgl:对象 obj
1 对象 object
1.1 对象 lv_obj_t
对象object:构建用户界面的基本单位,也称之为控件widgets;对于button,label,image,list等组件都可称之为对象;
//lv_obj.h 对象结构体; typedef struct _lv_obj_t { const lv_obj_class_t *class_p; struct _lv_obj_t *parent; _lv_obj_spec_attr_t *spec_attr; _lv_obj_style_t *styles; #if LV_USE_USER_DATA void *user_data; #endif lv_area_t coords; lv_obj_flag_t flags; lv_state_t state; uint16_t layout_inv : 1; uint16_t scr_layout_inv : 1; uint16_t skip_trans : 1; uint16_t style_cnt : 6; uint16_t h_layout : 1; uint16_t w_layout : 1; } lv_obj_t;
1.2 对象属性
1.2.1 基本属性 basic attributes
所有对象共享一些基本属性,如position,size,parent,styles,event handlers等等,可对其进行设置/获取,举例如下;
//obj的pos,class,style,draw,scroll属性等都有自己的xx.c和xx.h,可见obj的重要; //lv_obj_pos.h void lv_obj_set_pos(struct _lv_obj_t *obj, lv_coord_t x, lv_coord_t y); void lv_obj_set_size(struct _lv_obj_t *obj, lv_coord_t w, lv_coord_t h); lv_coord_t lv_obj_get_width(const struct _lv_obj_t *obj); //lv_obj_styles.h void lv_obj_add_style(struct _lv_obj_t *obj, lv_style_t *style, lv_style_selector_t selector); void lv_obj_refresh_style(struct _lv_obj_t *obj, lv_part_t part, lv_style_prop_t prop);
1.2.2 特定属性 specific attributes
一些对象拥有一些自己的特殊属性,所以一些对象也会拥有属于自己的特殊函数;
//lv_slider.h 位于widgets/下 static inline void lv_slider_set_range(lv_obj_t *obj, int32_t min, int32_t max); static inline void lv_slider_set_value(lv_obj_t *obj, int32_t value, lv_anim_enable_t anim);
1.2.3 父对象
每个对象只允许有一个父对象,父对象可视为子对象的容器,但是父对象可以允许有多个子对象;
每个子对象只有在父对象范围内可见,超出部分不可见;子对象会随着父对象的移动而移动;
lv_obj_t * parent = lv_obj_create(lv_scr_act()); /*Create a parent object on the current screen*/ lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/ lv_obj_t * obj1 = lv_obj_create(parent); /*Create an object on the previously created parent object*/ lv_obj_set_pos(obj1, 10, 10); /*Set the position of the new object*/ //lv_obj.c lv_obj_create()
1.3 创建/删除对象
/** //lv_obj.h * Create a base object (a rectangle) * @param parent pointer to a parent object. If NULL then a screen will be created. * @return pointer to the new object */ lv_obj_t *lv_obj_create(lv_obj_t *parent); /** //lv_obj_tree.h * Delete an object and all of its children. * Also remove the objects from their group and remove all animations (if any). * Send `LV_EVENT_DELETED` to deleted objects. * @param obj pointer to an object */ void lv_obj_del(struct _lv_obj_t *obj); /** //lv_obj_tree.h * Helper function for asynchronously deleting objects. * Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent). * @param obj object to delete * @see lv_async_call cae在lv_timer周期性回调的时候来删除对象,通常是1ms之后删除,看tick; */ void lv_obj_del_async(struct _lv_obj_t *obj); /** //lv_obj_tree.h * Delete all children of an object. * Also remove the objects from their group and remove all animations (if any). * Send `LV_EVENT_DELETED` to deleted objects. * @param obj pointer to an object */ void lv_obj_clean(struct _lv_obj_t *obj);
2 屏幕 screen
屏幕属于没有parent的obj,屏幕本身也还是obj,可以用创建obj的方式来创建屏幕;
大约屏幕没啥内容,但是呢又很常见无处不在,屏幕本身也还是obj,所以lvgl把屏幕也概括在了obj章节里;
2.1 创建屏幕
//对象在创建的时候如果还没有创建好屏幕,那么对象也可以作为屏幕; lv_obj_t * scr1 = lv_obj_create(NULL);
2.2 加载屏幕
lv_scr_act( ), lv_src_load( ), lv_src_load_anim( )都是在default screen上操作的;
每个screen都是创建在default display上的;default display是最后一个用lv_disp_drv_register( )注册的显示;
// 每个屏幕加载之后会在tick时间后更新,也可能是屏幕会在调用lv_scr_act()之后tick时间更新,先放着; /** lv_disp.h 获取当前屏幕 * Get the active screen of the default display * @return pointer to the active screen */ static inline lv_obj_t * lv_scr_act(void) { return lv_disp_get_scr_act(lv_disp_get_default()); } //lv_disp.h 加载屏幕 static inline void lv_scr_load(lv_obj_t * scr) { lv_disp_load_scr(scr); } /** lv_disp.c * Make a screen active * @param scr pointer to a screen */ void lv_disp_load_scr(lv_obj_t * scr) { lv_scr_load_anim(scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, false); }
2.3 动画加载屏幕
typedef enum { LV_SCR_LOAD_ANIM_NONE, //cae无动画,就是直接加载; LV_SCR_LOAD_ANIM_OVER_LEFT, //cae新屏幕以定向覆盖的方式来加载; LV_SCR_LOAD_ANIM_OVER_RIGHT, LV_SCR_LOAD_ANIM_OVER_TOP, LV_SCR_LOAD_ANIM_OVER_BOTTOM, LV_SCR_LOAD_ANIM_MOVE_LEFT, //cae新旧屏幕一起定向加载; LV_SCR_LOAD_ANIM_MOVE_RIGHT, LV_SCR_LOAD_ANIM_MOVE_TOP, LV_SCR_LOAD_ANIM_MOVE_BOTTOM, LV_SCR_LOAD_ANIM_FADE_IN, //cae在旧屏幕上淡入新屏幕; LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/ LV_SCR_LOAD_ANIM_FADE_OUT, LV_SCR_LOAD_ANIM_OUT_LEFT, //cae以旧屏幕定向滑出的方式来加载; LV_SCR_LOAD_ANIM_OUT_RIGHT, LV_SCR_LOAD_ANIM_OUT_TOP, LV_SCR_LOAD_ANIM_OUT_BOTTOM, } lv_scr_load_anim_t; /** //lv_disp.h 以动画方式加载屏幕,本质还是屏幕,而不是动画; * Switch screen with animation * @param scr pointer to the new screen to load * @param anim_type type of the animation from `lv_scr_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT` * @param time time of the animation * @param delay delay before the transition * @param auto_del true: automatically delete the old screen */ void lv_scr_load_anim(lv_obj_t * scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del);
2.4 层 layers
对于屏幕而言,每个屏幕上都有两层layer,分别是top layer和system layer;
top layer位于所有obj之上,top layer主要用来放置弹出窗口;
system layer位于top layer之上;system layer只能放置系统层控件,比如鼠标等;
/** //lv_disp.h * Get the top layer of the default display * @return pointer to the top layer */ static inline lv_obj_t *lv_layer_top(void) { return lv_disp_get_layer_top(lv_disp_get_default()); } //example: lv_obj_t *bg = lv_layer_top(); lv_obj_set_style_bg_color(bg, lv_color_hex(0x6f8af6), 0);
/** //lv_disp.h * Get the active screen of the default display * @return pointer to the sys layer */ static inline lv_obj_t *lv_layer_sys(void) { return lv_disp_get_layer_sys(lv_disp_get_default()); } //eg: perf_label = lv_label_create(lv_layer_sys()); lv_obj_set_style_bg_opa(perf_label, LV_OPA_50, 0);
3 坐标 coordinates
坐标方向:以父类左上角的坐标为原点,水平方向以x轴正方向为lvgl_obj正方向,垂直方向以y轴负方向为lvgl_obj正方向;
坐标单位:数值的单位都是像素点 pixels;
坐标存储:lvgl的坐标信息是存储在styles中的;所以可以单独设置坐标信息,也可以使用style对其进行设置;
3.1 位置 positions
3.1.1 位置 position
//lv_obj_pos.h void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y); void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x); void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y); void lv_obj_refr_pos(struct _lv_obj_t * obj); //用法保持怀疑,在tick范围内刷新一遍的话应该不调用也行;
3.1.2 对齐 align
//lv_area.h //child_obj向parent_obj对齐,使用LV_ALIGN_XX,在parent_obj内对齐,以child_obj顶点作为偏移坐标原点; // 使用LV_ALIGN_OUT_XX,对齐无效,坐标原点始终是父对象坐标原点;所以不要这么用; //align_obj向base_obj对齐, 使用LV_ALIGN_OUT_XX,偏移坐标原点为对齐后align_obj原点; enum _lv_align_t { LV_ALIGN_DEFAULT = 0, LV_ALIGN_TOP_LEFT, LV_ALIGN_TOP_MID, LV_ALIGN_TOP_RIGHT, LV_ALIGN_BOTTOM_LEFT, LV_ALIGN_BOTTOM_MID, LV_ALIGN_BOTTOM_RIGHT, LV_ALIGN_LEFT_MID, LV_ALIGN_RIGHT_MID, LV_ALIGN_CENTER, LV_ALIGN_OUT_TOP_LEFT, LV_ALIGN_OUT_TOP_MID, LV_ALIGN_OUT_TOP_RIGHT, LV_ALIGN_OUT_BOTTOM_LEFT, LV_ALIGN_OUT_BOTTOM_MID, LV_ALIGN_OUT_BOTTOM_RIGHT, LV_ALIGN_OUT_LEFT_TOP, LV_ALIGN_OUT_LEFT_MID, LV_ALIGN_OUT_LEFT_BOTTOM, LV_ALIGN_OUT_RIGHT_TOP, LV_ALIGN_OUT_RIGHT_MID, LV_ALIGN_OUT_RIGHT_BOTTOM, }; #ifdef DOXYGEN typedef _lv_align_t lv_align_t; #else typedef uint8_t lv_align_t; #endif /*DOXYGEN*/
//lv_obj_pos.h //obj向parent对齐,所以不是设计用来配置LV_ALIGN_OUT_XX的; void lv_obj_align(lv_obj_t * obj, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs); void lv_obj_set_align(lv_obj_t * obj, lv_align_t align); //obj向base对齐,对齐之后以obj顶点作为坐标原点 //LV_ALIGN_OUT_XX:obj在base_obj外对齐; //LV_ALIGN_XX: obj在base_obj内对齐; void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs)
3.2 尺寸 size
//lv_obj_pos.h void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h); void lv_obj_set_width(struct _lv_obj_t * obj, lv_coord_t w); //w: padding left + contain width + padding right void lv_obj_set_height(struct _lv_obj_t * obj, lv_coord_t h); //h: padding top + contain height + padding bottom bool lv_obj_refr_size(struct _lv_obj_t * obj); /** * Get the width reduced by the left and right padding and the border width. * @param obj pointer to an object * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation * call `lv_obj_update_layout(obj)`. * @return the width which still fits into its parent without causing overflow (making the parent scrollable) */ lv_coord_t lv_obj_get_content_width(const struct _lv_obj_t * obj); /** * Get the height reduced by the top and bottom padding and the border width. * @param obj pointer to an object * @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation * call `lv_obj_update_layout(obj)`. * @return the height which still fits into the parent without causing overflow (making the parent scrollable) */ lv_coord_t lv_obj_get_content_height(const struct _lv_obj_t * obj);
3.3 布局 layouts
用来更新当前对象子类的position和size,和flexbox、grid部件一起使用,对布局进行实时更新么?先放着;
//lv_obj_pos.h layout函数并不多,先放着; extern uint16_t LV_LAYOUT_GRID; //lv_grid.h extern uint16_t LV_LAYOUT_FLEX; //lv_flex.h void lv_obj_set_layout(struct _lv_obj_t * obj, uint32_t layout);
3.3.1 flags
用来配置子类对象 如何响应他的父类对象的layout局部;所以这个flag是layout给子类对象使用的;
//lv_obj.h /** * On/Off features controlling the object's behavior. * OR-ed values are possible */ enum { LV_OBJ_FLAG_HIDDEN = (1L << 0), /**< Make the object hidden. (Like it wasn't there at all)*/ LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/ LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/ LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/ LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/ LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/ LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/ LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/ LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/ LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/ LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER), LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/ LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/ LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/ LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/ LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/ LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/ LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/ LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object ignored by layouts,so obj can be set as usual*/ LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout,这个等于上一行那个*/ LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 19), /**< Do not clip the children's content to the parent's boundary*/ LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/ LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/ LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/ LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/ LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/ LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/ LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/ LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/ }; typedef uint32_t lv_obj_flag_t; /** * Set one or more flags * @param obj pointer to an object * @param f R-ed values from `lv_obj_flag_t` to set. */ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f); /** * Clear one or more flags * @param obj pointer to an object * @param f OR-ed values from `lv_obj_flag_t` to set. */ void lv_obj_clear_flag(lv_obj_t * obj, lv_obj_flag_t f);
4 小结
对象obj,对象的基本属性,特殊属性,父对象,增删对象;
屏幕也是对象,屏幕的创建加载删除;
然后坐标设置,坐标的定义和使用,其中有layout和flag的作用;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
2020-08-24 FPGA:PLL&RAM的原理及代码
2020-08-24 器件:AD8369&AD9203的原理与使用