02LVGL图形界面——widgets小部件

一、⭐LVGL 核心事件

LVGL每个对象每时每刻都在产生各种各样的事件,用户可以把自己需要的事件注册一个回调函数,当事件触发时,去执行该函数。

例如:一个按钮被点击, 一个文本框有数据输入 ......

官方事件注册例子

//按钮事件回调函数,当按钮被点击时,则执行该函数
static void event_cb(lv_event_t * e)
{
    LV_LOG_USER("Clicked");

    static uint32_t cnt = 1;
    lv_obj_t * btn = lv_event_get_target(e);
    lv_obj_t * label = lv_obj_get_child(btn, 0);
    lv_label_set_text_fmt(label, "%"LV_PRIu32, cnt);
    cnt++;
}

/**
 * Add click event to a button
 */
void lv_example_event_1(void)
{
    //1.在屏幕上创建一个按钮对象 
    lv_obj_t * btn = lv_button_create(lv_screen_active());
    //2.设置按钮的大小  
    lv_obj_set_size(btn, 100, 50);
    //3.把按钮放入中央
    lv_obj_center(btn);
    //4.⭐给按钮添加  LV_EVENT_CLICKED 点击事件  👉event_cb  回调函数 
    lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
    
    //在按钮上创建一个标签对象 
    lv_obj_t * label = lv_label_create(btn);
    //设置标签的文本
    lv_label_set_text(label, "Click me!");
    //把标签放入按钮的中央
    lv_obj_center(label);
}

最简单的事件注册方法

//当按钮被点击时就会执行该函数
void button_cb(lv_event_t *e) 
{
    printf("按钮被点击啦\n");
}

// 1.创建按钮对象
lv_obj_t * btn = lv_button_create(lv_screen_active());
//给按钮注册一个,事件回调函数 
lv_obj_add_event_cb(btn, button_cb, LV_EVENT_CLICKED, NULL);


练习:定义两个按钮对象,注册两个不同的回调函数! 测试按钮是否, 能触发回调函数! 

二、事件函数接口

/**
 * Add an event handler function for an object.
 * Used by the user to react on event which happens with the object.
 * An object can have multiple event handler. They will be called in the same order as they were added.
 * @param obj       pointer to an object
 * @param filter    an event code (e.g. `LV_EVENT_CLICKED`) on which the event should be called. `LV_EVENT_ALL` can be used to receive all the events.
 * @param event_cb  the new event function
 * @param           user_data custom data data will be available in `event_cb`
 * @return          handler to the event. It can be used in `lv_obj_remove_event_dsc`.
 */
 //添加对象事件处理函数 
lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data);
obj:需要添加事件的对象
event_cb:事件回调函数 typedef void (*lv_event_cb_t)(lv_event_t *e) ,事件函数必须设计为  void  函数名(lv_event_t *e)
filter:事件号 
user_data:传递给事件函数的参数


例子:注册一个按钮点击事件 
void button_cb(lv_event_t *e) 
{
    printf("按钮被点击啦\n");
}
lv_obj_t * btn = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn, button_cb, LV_EVENT_CLICKED, NULL);

例子:注册按钮的所有事件
void button_cb(lv_event_t *e) 
{
    printf("按钮被点击啦\n");
}
lv_obj_t * btn = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn, button_cb, LV_EVENT_ALL, NULL);

Events(事件) — LVGL 文档 事件号

LV_EVENT_PRESSED:✔️ 对象已被按下
LV_EVENT_PRESSING: 对象正在被按下(在按下期间持续调用)
LV_EVENT_PRESS_LOST: 对象仍在被按下,但滑动光标/手指离开对象
LV_EVENT_SHORT_CLICKED: 对象被按下一小段时间,然后释放。如果被滚动,则不会被调用。
LV_EVENT_LONG_PRESSED: 对象至少被按下`long_press_time`。如果被滚动,则不会被调用。
LV_EVENT_LONG_PRESSED_REPEAT: 在每`long_press_repeat_time`(长按重复时间)毫秒后,调用一次。如果被滚动,则不会被调用。
LV_EVENT_CLICKED: ✔️如果没有被滚动,在释放时被调用(与长按无关)
LV_EVENT_RELEASED: ✔️在任何对象释放时被调用
LV_EVENT_SCROLL_BEGIN: 滚动开始。事件参数是滚动动画的指针。可以被修改
LV_EVENT_SCROLL_THROW_BEGIN:
LV_EVENT_SCROLL_END: 滚动结束
LV_EVENT_SCROLL: 滚动中
LV_EVENT_GESTURE: 检测到手势。使用 lv_indev_get_gesture_dir(lv_indev_active()); 获取手势
LV_EVENT_KEY: 将键发送给对象。使用 lv_indev_get_key(lv_indev_active()); 获取键值
LV_EVENT_FOCUSED: 对象获得焦点
LV_EVENT_DEFOCUSED: 对象失去焦点
LV_EVENT_LEAVE: 对象失去焦点但仍然被选中
LV_EVENT_HIT_TEST: 执行高级点击测试
LV_EVENT_INDEV_RESET: 输入设备已重置
LV_EVENT_HOVER_OVER: 输入设备悬停在对象上方。
LV_EVENT_HOVER_LEAVE: 输入设备离开对象上方的悬停状态。

/**
 * Type of event being sent to the object.
 */
typedef enum {
    LV_EVENT_ALL = 0,   ✔️注册下述所有事件 

    /** Input device events*/
    LV_EVENT_PRESSED,             /**< ✔️按下 The object has been pressed*/
    LV_EVENT_PRESSING,            /**< The object is being pressed (called continuously while pressing)*/
    LV_EVENT_PRESS_LOST,          /**< The object is still being pressed but slid cursor/finger off of the object */
    LV_EVENT_SHORT_CLICKED,       /**< The object was pressed for a short period of time, then released it. Not called if scrolled.*/
    LV_EVENT_LONG_PRESSED,        /**< Object has been pressed for at least `long_press_time`.  Not called if scrolled.*/
    LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `long_press_time` in every `long_press_repeat_time` ms.  Not called if scrolled.*/
    LV_EVENT_CLICKED,             /**< ✔️点击 Called on release if not scrolled (regardless to long press)*/
    LV_EVENT_RELEASED,            /**< ✔️松开 Called in every cases when the object has been released*/
    LV_EVENT_SCROLL_BEGIN,        /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified*/
    LV_EVENT_SCROLL_THROW_BEGIN,
    LV_EVENT_SCROLL_END,          /**< Scrolling ends*/
    LV_EVENT_SCROLL,              /**< Scrolling*/
    LV_EVENT_GESTURE,             /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */
    LV_EVENT_KEY,                 /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_active());`*/
    LV_EVENT_FOCUSED,             /**< The object is focused*/
    LV_EVENT_DEFOCUSED,           /**< The object is defocused*/
    LV_EVENT_LEAVE,               /**< The object is defocused but still selected*/
    LV_EVENT_HIT_TEST,            /**< Perform advanced hit-testing*/
    LV_EVENT_INDEV_RESET,         /**< Indev has been reset*/

    /** Drawing events*/
    LV_EVENT_COVER_CHECK,        /**< Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.*/
    LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get the required extra draw area around the object (e.g. for shadow). The event parameter is `int32_t *` to store the size.*/
    LV_EVENT_DRAW_MAIN_BEGIN,    /**< Starting the main drawing phase*/
    LV_EVENT_DRAW_MAIN,          /**< Perform the main drawing*/
    LV_EVENT_DRAW_MAIN_END,      /**< Finishing the main drawing phase*/
    LV_EVENT_DRAW_POST_BEGIN,    /**< Starting the post draw phase (when all children are drawn)*/
    LV_EVENT_DRAW_POST,          /**< Perform the post draw phase (when all children are drawn)*/
    LV_EVENT_DRAW_POST_END,      /**< Finishing the post draw phase (when all children are drawn)*/
    LV_EVENT_DRAW_TASK_ADDED,      /**< Adding a draw task */

    /** Special events*/
    LV_EVENT_VALUE_CHANGED,       /**< The object's value has changed (i.e. slider moved)*/
    LV_EVENT_INSERT,              /**< A text is inserted to the object. The event data is `char *` being inserted.*/
    LV_EVENT_REFRESH,             /**< Notify the object to refresh something on it (for the user)*/
    LV_EVENT_READY,               /**< A process has finished*/
    LV_EVENT_CANCEL,              /**< A process has been cancelled */

    /** Other events*/
    LV_EVENT_CREATE,              /**< Object is being created*/
    LV_EVENT_DELETE,              /**< Object is being deleted*/
    LV_EVENT_CHILD_CHANGED,       /**< Child was removed, added, or its size, position were changed */
    LV_EVENT_CHILD_CREATED,       /**< Child was created, always bubbles up to all parents*/
    LV_EVENT_CHILD_DELETED,       /**< Child was deleted, always bubbles up to all parents*/
    LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called*/
    LV_EVENT_SCREEN_LOAD_START,   /**< A screen load started, fired when the screen change delay is expired*/
    LV_EVENT_SCREEN_LOADED,       /**< A screen was loaded*/
    LV_EVENT_SCREEN_UNLOADED,     /**< A screen was unloaded*/
    LV_EVENT_SIZE_CHANGED,        /**< Object coordinates/size have changed*/
    LV_EVENT_STYLE_CHANGED,       /**< Object's style has changed*/
    LV_EVENT_LAYOUT_CHANGED,      /**< The children position has changed due to a layout recalculation*/
    LV_EVENT_GET_SELF_SIZE,       /**< Get the internal size of a widget*/

    /** Events of optional LVGL components*/
    LV_EVENT_INVALIDATE_AREA,
    LV_EVENT_RESOLUTION_CHANGED,
    LV_EVENT_COLOR_FORMAT_CHANGED,
    LV_EVENT_REFR_REQUEST,
    LV_EVENT_REFR_START,
    LV_EVENT_REFR_READY,
    LV_EVENT_RENDER_START,
    LV_EVENT_RENDER_READY,
    LV_EVENT_FLUSH_START,
    LV_EVENT_FLUSH_FINISH,
    LV_EVENT_FLUSH_WAIT_START,
    LV_EVENT_FLUSH_WAIT_FINISH,

    LV_EVENT_VSYNC,

    _LV_EVENT_LAST,                 /** Number of default events*/

    LV_EVENT_PREPROCESS = 0x8000,   /** This is a flag that can be set with an event so it's processed
                                      before the class default event processing */
} lv_event_code_t;

例子:注册-按下-松开-点击事件

void button_cb(lv_event_t * e)
{
    printf("按钮被点击啦\n");
}

void button_cb_press(lv_event_t * e)
{
    printf("按钮被按下\n");
}

void button_cb_releas(lv_event_t * e)
{
    printf("按钮被松开\n");
}
      
// 1.创建按钮对象
lv_obj_t * btn = lv_button_create(lv_screen_active());
// 2.设置按钮的大小
lv_obj_set_size(btn, 100, 50);
lv_obj_add_event_cb(btn, button_cb, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(btn, button_cb_press, LV_EVENT_PRESSED, NULL);
lv_obj_add_event_cb(btn, button_cb_releas, LV_EVENT_RELEASED, NULL);

三、事件过滤

先把所有事件注册到对象中,再通过 lv_event_code_t  lv_event_get_code(lv_event_t *e) 过滤事件号

void button_cb(lv_event_t * e)
{
    // 获取事件号
    lv_event_code_t code = lv_event_get_code(e);

    // 进行过滤判断
    if(code == LV_EVENT_CLICKED) {
        printf("按钮点击\n");
    } else if(code == LV_EVENT_PRESSED) {
        printf("按钮按下\n");
    } else if(code == LV_EVENT_RELEASED) {
        printf("按钮松开\n");
    }
}

lv_obj_t * btn = lv_button_create(lv_screen_active());
lv_obj_add_event_cb(btn, button_cb, LV_EVENT_ALL, NULL);

四、获取触发事件对象

作用:如果有多个对象同时注册同一个事件处理函数,通过获取触发对象,即可得到那个对象触发该事件。

void * lv_event_get_target(lv_event_t * e);   //获取当前触发事件的对象 


lv_obj_t * btn; 
lv_obj_t * btn1;
lv_obj_t * btn2;

static void event_cb(lv_event_t * e)
{
    // 获取当前触发事件的对象
    void * obj = lv_event_get_target(e);

    printf("按钮被点击  %p\n", obj);

    if(btn == obj) {
        printf("按钮 0 点击\n");
    } else if(btn1 == obj) {
        printf("按钮 1 点击\n");
    } else if(btn2 == obj) {
        printf("按钮 2 点击\n");
    }
}

void my_bt()
{
    // 1.在屏幕上创建一个按钮对象
    btn = lv_button_create(lv_screen_active());
    // 在按钮上创建一个标签对象
    lv_obj_t * label = lv_label_create(btn);
    // 设置标签的文本
    lv_label_set_text(label, "0");
    // 把标签放入按钮的中央
    lv_obj_center(label);

    btn1 = lv_button_create(lv_screen_active());
    // 在按钮上创建一个标签对象
    lv_obj_t * label1 = lv_label_create(btn1);
    // 设置标签的文本
    lv_label_set_text(label1, "1");
    // 把标签放入按钮的中央
    lv_obj_center(label1);

    btn2 = lv_button_create(lv_screen_active());
    // 在按钮上创建一个标签对象
    lv_obj_t * label2 = lv_label_create(btn2);
    // 设置标签的文本
    lv_label_set_text(label2, "2");
    // 把标签放入按钮的中央
    lv_obj_center(label2);

    lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);
    lv_obj_align_to(btn, btn1, LV_ALIGN_OUT_LEFT_MID, -10, 0);
    lv_obj_align_to(btn2, btn1, LV_ALIGN_OUT_RIGHT_MID, 10, 0);

    lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_add_event_cb(btn1, event_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_add_event_cb(btn2, event_cb, LV_EVENT_CLICKED, NULL);
}

练习:利用获取事件对象,指针一个数字键盘  判断用户输入的  0  -  9  

五、事件传参

void * lv_event_get_user_data(lv_event_t * e); 获取用注册时传递的用户数据

六、Widgets 控件

LVGL 控件的学习方法,阅读官方使用手册查看示例掌握函数接口的应用即可

Widgets(控件) — LVGL 文档

label 标签

/**
 * Show line wrap, re-color, line align and text scrolling.
 */
void lv_example_label_1(void)
{
    //创建标签对象  
    lv_obj_t * label1 = lv_label_create(lv_screen_active());
    //设置标签文本显示方式
    lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP);     /*Break the long lines 换行*/
    //设置标签文本
    lv_label_set_text(label1, "Recolor is not supported for v9 now.");
    lv_obj_set_width(label1, 150);  /*Set smaller width to make the lines wrap*/
    lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);   //设置文本的对齐规则
    lv_obj_align(label1, LV_ALIGN_CENTER, 0, -40);

    lv_obj_t * label2 = lv_label_create(lv_screen_active());
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR);     /*Circular scroll 圆形滚动*/
    lv_obj_set_width(label2, 150);
    lv_label_set_text(label2, "It is a circularly scrolling text. ");
    lv_obj_align(label2, LV_ALIGN_CENTER, 0, 40);
}

//设置长文本的行为
void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode)
obj:需要设置的标签对象 
long_mode:
/** Long mode behaviors. Used in 'lv_label_ext_t'*/
enum _lv_label_long_mode_t {
LV_LABEL_LONG_WRAP,             /**< 换行 Keep the object width, wrap lines longer than object width and expand the object height*/
LV_LABEL_LONG_DOT,              /**< 末尾.. Keep the size and write dots at the end if the text is too long*/
LV_LABEL_LONG_SCROLL,           /**< 滚动效果 Keep the size and roll the text back and forth*/
LV_LABEL_LONG_SCROLL_CIRCULAR,  /**< 圆形滚动 Keep the size and roll the text circularly*/
LV_LABEL_LONG_CLIP,             /**< 戒断 Keep the size and clip the text out of it*/
};

//获取标签的文本信息 
char *lv_label_get_text(const lv_obj_t *obj)

//设置标签文本
void lv_label_set_text(lv_obj_t *obj, const char *text)

//设置标签显示格式  
void lv_label_set_text_fmt(lv_obj_t *obj, const char *fmt, ...)

//设置标签字体大小
lv_obj_set_style_text_font(lv_obj_t *obj, &lv_font_montserrat_28, 0);
//lv_font_montserrat_28 字体大小 

七、Image 图像

 void lv_example_image_1(void)
{ 
    //声明一个图像变量  
    LV_IMAGE_DECLARE(img_cogwheel_argb);
    //创建图形对象 
    lv_obj_t * img1 = lv_image_create(lv_screen_active());
    //设置图像源
    lv_image_set_src(img1, &img_cogwheel_argb);
    //居中显示 
    lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
    //创建图形对象
    lv_obj_t * img2 = lv_image_create(lv_screen_active());
    //设置图片源
    lv_image_set_src(img2, LV_SYMBOL_OK "Accept");
    lv_obj_align_to(img2, img1, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
}

函数接口设置图片源 
lv_image_set_src(img, src) 
src:需要设置的图片源
1.代码中的变量(带有像素的 C 数组)。
2.外部存储的文件(例如在 SD 卡上)。  👉lv_image_set_src(img, "S:folder1/my_img.bin")  设置图片路径
3.带有 Symbols 的文本。

支持的图标显示

// 创建一个图片对象
    lv_obj_t * img1 = lv_image_create(lv_screen_active());
    //设置 SYMBOL 图片源 
    //lv_image_set_src(img1, LV_SYMBOL_WIFI); 
    //设置自己的图片源 
    lv_image_set_src(img1, "A:/home/gec/20.bmp"); 

八、C数组显示png

Image Converter — LVGL 图片转数组工具

把转换后的文件拷贝到LVGL工程中

添加图片到工程中

显示代码

 // 声明图片
LV_IMAGE_DECLARE(gao);        // 声明图像数组
lv_image_set_src(img2, &gao); // 显示图像数组

图片操作

lv_image_set_scale(img, factor) 将缩放图像。 将 factor 设置为 
256 或 LV_SCALE_NONE 来禁用缩放。一个较大的值会放大图像
(例如 512 双倍尺寸),较小的值会缩小它(例如 128 半尺寸)。
lv_image_set_rotation(img, angle)。旋转 ,角度有 0.1 度精度,所以对于45.8°将设置458。 

⭐注意:注意,使用图片操作函数,必须把图片转换为 C 数组才生效! 

九、flag 标记添加

默认情况下某些控件只能查看无法操作,如果用户想要给控件添加操作功能,则需要添加操作标志。

/**
 * 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);


/**
 * Remove 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_remove_flag(lv_obj_t * obj, lv_obj_flag_t f);


//例子:给图片添加点击标记 
lv_obj_t * img = lv_image_create(lv_screen_active());
lv_obj_add_flag(img,LV_OBJ_FLAG_CLICKABLE); //👉 给图片添加点击功能
lv_obj_add_event_cb(img, img_clicked, LV_EVENT_CLICKED, NULL);

1、控件标记表格

/**
 * On/Off features controlling the object's behavior.
 * OR-ed values are possible
 *
 * Note: update obj flags corresponding properties below
 * whenever add/remove flags or change bit definition of flags.
 */
typedef 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 position-able by the layouts*/
    LV_OBJ_FLAG_FLOATING        = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/
    LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/
    LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/
#if LV_USE_FLEX
    LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21),     /**< Start a new flex track on this item*/
#endif

    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*/
} _lv_obj_flag_t;

2、无背景控件制作

在线抠图软件_图片去除背景 | remove.bg – remove.bg

1.把控件素材图的背景删除

2.把控件素材转换为C数组

十、Bar 进度条

 //创建进度条对象
 lv_obj_t * bar1 = lv_bar_create(lv_screen_active());
//设置进度条的值 

lv_bar_set_value(bar, new_value, LV_ANIM_ON/OFF)
bar:进度条对象 
new_value:新的值  
动画:LV_ANIM_ON 开启 / LV_ANIM_OFF 关闭动画 

//设置进度条范围 
lv_bar_set_range(bar, min, max)
bar:进度条对象  
min:最小值 
max:最大值  

十一、Slider  滑动条

//创建滑块
lv_obj_t * slider = lv_slider_create(lv_screen_active());
//设置滑块当前值
lv_slider_set_value(slider, new_value, LV_ANIM_ON / OFF) 
//设置滑块范围
lv_slider_set_range(slider, min, max)

 
事件👇
LV_EVENT_VALUE_CHANGED  在拖动滑块或用键更改。当滑块处于被拖拽。
LV_EVENT_RELEASED       在刚刚释放滑块时发送。 

进度与滑块demo

// 滑块事件
void slider_event(lv_event_t * e)
{
    printf("滑块值变化\n");

    lv_obj_t * slider = lv_event_get_target(e);

    // 获取传递过来的进度条对象
    lv_obj_t * bar = lv_event_get_user_data(e);

    // 获取滑块的当前值
    int value = lv_slider_get_value(slider);
    printf("value=%d\n", value);

    // 设置进度条的值
    lv_bar_set_value(bar, value, LV_ANIM_ON);
}
-------------------------------------------------------------
   // 创建进度条对象
    lv_obj_t * bar1 = lv_bar_create(lv_screen_active());
    // 设置进度条范围
    lv_bar_set_range(bar1, 0, 100);
    // 设置进度条当前值
    lv_bar_set_value(bar1, 0, LV_ANIM_ON);
    lv_obj_center(bar1);

    // 创建一个滑块对象
    lv_obj_t * slider = lv_slider_create(lv_screen_active());
    // 设置滑块范围
    lv_slider_set_range(slider, 0, 100);

    lv_obj_align(slider, LV_ALIGN_CENTER, 0, -100);

    // 添加滑块事件
    lv_obj_add_event_cb(slider, slider_event, LV_EVENT_VALUE_CHANGED, bar1);

十二、Textarea 文本输入框

//创建文本对象 
lv_obj_t * pwd_ta = lv_textarea_create(lv_screen_active());

//添加一个字符
lv_textarea_add_char(textarea, 'c')
//添加字符串
lv_textarea_add_text(textarea, "insert this text")
//添加提示信息
lv_textarea_set_placeholder_text(ta, "Placeholder text")

//删除光标左侧的字符
lv_textarea_delete_char(textarea)。
//从光标右侧删除字符
lv_textarea_delete_char_forward(textarea)。
//当行模式
lv_textarea_set_one_line(textarea, true)
//密码模式 
lv_textarea_set_password_mode(textarea, true)
//获取文本 
lv_textarea_get_text(textarea)


⭐文本输入框需要与键盘配合使用  
/*创建一个键盘*/
lv_obj_t *  kb = lv_keyboard_create(lv_screen_active());
lv_keyboard_set_textarea(kb, pwd_ta); /*👍 把键盘设置到文本输入框中*/

demo 输入框与键盘例子

void keyboard_show(lv_event_t * e)
{
    // 获取键盘对象
    lv_obj_t * kb = lv_event_get_user_data(e);
    // 显示键盘
    lv_obj_remove_flag(kb, LV_OBJ_FLAG_HIDDEN);
}

void keyboard_hide(lv_event_t * e)
{
    lv_obj_t * kb = lv_event_get_user_data(e);
    // 隐藏键盘
    lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
}

//创建文本对象
lv_obj_t * pwd_ta = lv_textarea_create(lv_screen_active());
// 设置文本框的大小
// lv_obj_set_size(pwd_ta, 200, 100);
// 设置单行模式
lv_textarea_set_one_line(pwd_ta, true);
// 添加提示信息
lv_textarea_set_placeholder_text(pwd_ta, "PleaseEnterYourAccount");
// 放入中央
lv_obj_center(pwd_ta);

/*创建一个键盘*/
lv_obj_t * kb = lv_keyboard_create(lv_screen_active());
lv_obj_align(kb, LV_ALIGN_BOTTOM_MID, 0, 0);
// 设置键盘大小
lv_obj_set_size(kb, 400, 200);
lv_keyboard_set_textarea(kb, pwd_ta); /*👍 把键盘设置到文本输入框中*/
// 隐藏键盘
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);

// 注册焦点事件
lv_obj_add_event_cb(pwd_ta, keyboard_show, LV_EVENT_FOCUSED, kb);
lv_obj_add_event_cb(pwd_ta, keyboard_hide, LV_EVENT_DEFOCUSED, kb);

十三、多输入框设计思路

十四、Message box(消息框)

demo

static void event_cb(lv_event_t * e)
{
    lv_obj_t * btn = lv_event_get_target(e);
    lv_obj_t * label = lv_obj_get_child(btn, 0);
    LV_UNUSED(label);
    LV_LOG_USER("Button %s clicked", lv_label_get_text(label));
}

void lv_example_msgbox_1(void)
{  
    //创建消息框
    lv_obj_t * mbox1 = lv_msgbox_create(NULL);
    
    //添加标题
    lv_msgbox_add_title(mbox1, "Hello");
    //添加提示信息
    lv_msgbox_add_text(mbox1, "This is a message box with two buttons.");
    //添加关闭按钮 
    lv_msgbox_add_close_button(mbox1);

    lv_obj_t * btn; 
    //添加选择按钮 
    btn = lv_msgbox_add_footer_button(mbox1, "Apply");
    lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
    btn = lv_msgbox_add_footer_button(mbox1, "Cancel");
    lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);
    return;
}

十五、自定义消息框

void * yes_bt(lv_event_t * e)
{
    lv_obj_t * mbox1 = lv_event_get_user_data(e);

    printf("yes\n");

    // 删除消息框
    lv_obj_delete(mbox1);
}
------------------------------------------------------------
  // 创建一个消息框
    lv_obj_t * mbox1 = lv_msgbox_create(lv_screen_active());
    // 添加标题
    lv_msgbox_add_title(mbox1, "loin_msg");
    // 添加提示信息
    lv_msgbox_add_text(mbox1, "loin Success!");
    // 添加关闭按钮
    lv_msgbox_add_close_button(mbox1);
    // 添加选择按钮
    lv_obj_t * bt = lv_msgbox_add_footer_button(mbox1, "YES");
    // 添加事件
    lv_obj_add_event_cb(bt, yes_bt, LV_EVENT_CLICKED, mbox1);

十六、Tabview  表格试图

#include "../../lv_examples.h"
#if LV_USE_TABVIEW && LV_BUILD_EXAMPLES

/*A vertical tab view with disabled scrolling and some styling*/
void lv_example_tabview_2(void)
{
    /*Create a Tab view object*/
    lv_obj_t * tabview;
    tabview = lv_tabview_create(lv_screen_active());   //创建表格试图
    lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT);  //设置表格试图的位置 
    lv_tabview_set_tab_bar_size(tabview, 80);  //设置选框的大小 
    //设置背景颜色
    lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0);
    //设置选项的特效
    lv_obj_t * tab_buttons = lv_tabview_get_tab_bar(tabview);
    lv_obj_set_style_bg_color(tab_buttons, lv_palette_darken(LV_PALETTE_GREY, 3), 0);
    lv_obj_set_style_text_color(tab_buttons, lv_palette_lighten(LV_PALETTE_GREY, 5), 0);
    lv_obj_set_style_border_side(tab_buttons, LV_BORDER_SIDE_RIGHT, LV_PART_ITEMS | LV_STATE_CHECKED);

    /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled ⭐ 添加表格选项*/ 
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
    lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
    lv_obj_t * tab3 = lv_tabview_add_tab(tabview, "Tab 3");
    lv_obj_t * tab4 = lv_tabview_add_tab(tabview, "Tab 4");
    lv_obj_t * tab5 = lv_tabview_add_tab(tabview, "Tab 5");

    lv_obj_set_style_bg_color(tab2, lv_palette_lighten(LV_PALETTE_AMBER, 3), 0);
    lv_obj_set_style_bg_opa(tab2, LV_OPA_COVER, 0);

    /*Add content to the tabs  在每个表格选项中添加标签*/
    lv_obj_t * label = lv_label_create(tab1);
    lv_label_set_text(label, "First tab");

    label = lv_label_create(tab2);
    lv_label_set_text(label, "Second tab");

    label = lv_label_create(tab3);
    lv_label_set_text(label, "Third tab");

    label = lv_label_create(tab4);
    lv_label_set_text(label, "Forth tab");

    label = lv_label_create(tab5);
    lv_label_set_text(label, "Fifth tab");
    
    //去除滑动标记
    lv_obj_remove_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
}
#endif

修改后的例子

 // 创建表格试图
    lv_obj_t * tabview = lv_tabview_create(lv_screen_active());

    // 设置表格在左边
    lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT); // 设置表格试图的位置

    // 添加表格选项
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
    lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
    lv_obj_t * tab3 = lv_tabview_add_tab(tabview, "Tab 3");
    lv_obj_t * tab4 = lv_tabview_add_tab(tabview, "Tab 4");
    lv_obj_t * tab5 = lv_tabview_add_tab(tabview, "Tab 5");

    // 在表格中添加标签
    lv_obj_t * label = lv_label_create(tab1);
    lv_label_set_text(label, "First tab");

    // 添加按钮
    lv_obj_t * bt = lv_button_create(tab2);

十七、LVGL 多界面设计

Displays(显示) — LVGL 文档

要创建一个屏幕对象, NULL 表示没有父级。
lv_obj_t * scr = lv_obj_create(NULL)。  //空白屏幕 

lv_screen_load(scr)  //加载屏幕

lv_screen_active() //获取活跃的屏幕 


/**
 * Switch screen with animation
 * @param scr       需要加载的屏幕
 * @param anim_type type of the animation from `lv_screen_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
 * @param time      动画时间
 * @param delay     延时切换
 * @param auto_del  true: automatically delete the old screen  自动删除旧屏幕
 */
void lv_screen_load_anim(lv_obj_t * scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay,
                         bool auto_del);
动画加载例子:
lv_screen_load_anim(ctrl_win,LV_SCR_LOAD_ANIM_OVER_TOP,2000,0,false);


加载动画类型:
    typedef enum {
    LV_SCR_LOAD_ANIM_NONE,
    LV_SCR_LOAD_ANIM_OVER_LEFT,
    LV_SCR_LOAD_ANIM_OVER_RIGHT,
    LV_SCR_LOAD_ANIM_OVER_TOP,
    LV_SCR_LOAD_ANIM_OVER_BOTTOM,
    LV_SCR_LOAD_ANIM_MOVE_LEFT,
    LV_SCR_LOAD_ANIM_MOVE_RIGHT,
    LV_SCR_LOAD_ANIM_MOVE_TOP,
    LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
    LV_SCR_LOAD_ANIM_FADE_IN,
    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,
    LV_SCR_LOAD_ANIM_OUT_RIGHT,
    LV_SCR_LOAD_ANIM_OUT_TOP,
    LV_SCR_LOAD_ANIM_OUT_BOTTOM,
} lv_screen_load_anim_t;

至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bardb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值