LVGL图表中游标左右移动问题

LVGL中,图表中设置的游标怎样进行左右移动呢,是通过触摸屏能自由的进行左右移动,然后左右移动过程中获取X轴的坐标,并且显示在游标的右边

  • 你看下这篇博客吧, 应该有用👉 :LVGL库实现的简单实时时钟表盘示例代码
  • 除此之外, 这篇博客: lvgl 小部件使用demo示例说明1中的 LVGL 基础对象使用介绍 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • lvgl的基础对象是实现屏幕上小部件的基本属性
    常用属性介绍如下所示:
    尺寸设置:

    //设置控件宽
    lv_obj_set_width(obj, new_width); 
    //设置控件高
    lv_obj_set_height(obj, new_height);
    //同时设置控件的宽高
    lv_obj_set_size(obj, new_width, new_height);
    

    位置设置:

    //设置控件X坐标
    lv_obj_set_x(obj,new_x)//设置控件Y坐标
    lv_obj_set_y(obj,new_y)//同时设置控件X,Y坐标
    lv_obj_set_pos(obj, new_x, new_y);
    

    对齐设置:
    根据官方文档对齐的方式有以下几种:
    在这里插入图片描述
    控件对象事件回调设置

    //为对象事件设置回调函数
    lv_obj_add_event_cb(obj, event_cb, LV_EVENT_..., user_data);
    //主动向控件对象发送事件
    lv_event_send(obj, LV_EVENT_..., param);
    
    //参考相对位置对齐
    lv_obj_set_align(obj, LV_ALIGN_CENTER);
    lv_obj_set_pos(obj, 10, 20);
    //Or in one function
    lv_obj_align(obj, LV_ALIGN_CENTER, 10, 20);
    
    //参考对象对齐
    lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y);
    

    控件状态设置

    /*
    LV_STATE_DEFAULT     =  0x0000,
    LV_STATE_CHECKED     =  0x0001,
    LV_STATE_FOCUSED     =  0x0002,
    LV_STATE_FOCUS_KEY   =  0x0004,
    LV_STATE_EDITED      =  0x0008,
    LV_STATE_HOVERED     =  0x0010,
    LV_STATE_PRESSED     =  0x0020,
    LV_STATE_SCROLLED    =  0x0040,
    LV_STATE_DISABLED    =  0x0080,
    */
    lv_obj_add_state(lv_obj_t * obj, lv_state_t state) //设置指定小部件的状态
    
  • 您还可以看一下 姜景隆老师的5个小时上手嵌入式操作系统课程中的 LVGL简介小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    经过查阅LVGL官方文档和相关示例,可以实现在LVGL图表的游标中通过触摸屏左右移动,并实时显示X轴坐标。具体步骤如下:

    1. 创建LVGL图表对象并设置样式
    lv_obj_t * chart = lv_chart_create(lv_scr_act());
    lv_chart_set_series_opa(chart, LV_OPA_70); //设置系列的透明度
    lv_obj_set_size(chart, 500, 200); //设置图表大小
    lv_obj_set_pos(chart, 50, 50); //设置图表位置
    
    1. 向图表中添加数据序列
    lv_chart_series_t * series = lv_chart_add_series(chart, LV_COLOR_RED); //添加数据系列
    lv_chart_set_point_count(chart, series, 50); //设置点数
    for (uint8_t i = 0; i < 50; i++) {
        lv_chart_set_next(chart, series, rand()%100); //添加数据
    }
    
    1. 创建游标对象并设置样式
    lv_obj_t * cursor = lv_obj_create(lv_scr_act()); //创建游标对象
    lv_obj_set_size(cursor, 2, 200); //设置游标大小
    lv_obj_set_pos(cursor, 50, 50); //设置游标位置
    lv_obj_set_style_local_bg_color(cursor, LV_STATE_DEFAULT, LV_COLOR_BLUE); //设置游标背景颜色
    
    1. 在触摸屏上添加事件处理函数,获取游标位置并根据位置计算X轴坐标值
    static lv_point_t last_point;
    
    static void chart_event_cb(lv_event_t * e)
    {
        lv_obj_t * chart = lv_event_get_target(e);
        lv_event_code_t code = lv_event_get_code(e);
        if (code == LV_EVENT_CLICKED || code == LV_EVENT_PRESSING) {
            lv_indev_t * indev = lv_event_get_data(); //获取触摸屏对象
            lv_point_t point;
            lv_indev_get_point(indev, &point); //获取触摸屏坐标
            lv_coord_t dx = point.x - last_point.x; //计算游标移动距离
            lv_obj_t * cursor = lv_obj_get_child(chart, 1); //获取游标对象
            lv_coord_t cursor_x = lv_obj_get_x(cursor);
            cursor_x += dx; //计算游标新位置
            if (cursor_x < 50) cursor_x = 50;
            else if (cursor_x > 550) cursor_x = 550;
            lv_obj_set_x(cursor, cursor_x); //更新游标位置
            lv_coord_t x_value = (cursor_x - 50) * 10 / 500; //计算X轴坐标值
            printf("X value: %d\n", x_value); //打印X轴坐标值
            last_point = point;
        }
    }
    
    lv_obj_set_event_cb(chart, chart_event_cb); //将事件处理函数与图表对象绑定
    

    此时,当在LVGL图表上通过触摸屏移动游标时,会实时显示X轴坐标值。完整代码如下所示:

    #include "lvgl/lvgl.h"
    
    static void chart_event_cb(lv_event_t * e)
    {
        lv_obj_t * chart = lv_event_get_target(e);
        lv_event_code_t code = lv_event_get_code(e);
        if (code == LV_EVENT_CLICKED || code == LV_EVENT_PRESSING) {
            lv_indev_t * indev = lv_event_get_data();
            lv_point_t point;
            lv_indev_get_point(indev, &point);
            lv_coord_t dx = point.x - last_point.x;
            lv_obj_t * cursor = lv_obj_get_child(chart, 1);
            lv_coord_t cursor_x = lv_obj_get_x(cursor);
            cursor_x += dx;
            if (cursor_x < 50) cursor_x = 50;
            else if (cursor_x > 550) cursor_x = 550;
            lv_obj_set_x(cursor, cursor_x);
            lv_coord_t x_value = (cursor_x - 50) * 10 / 500;
            printf("X value: %d\n", x_value);
            last_point = point;
        }
    }
    
    void lv_ex_chart_2(void)
    {
        lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(3), LV_GRID_TEMPLATE_LAST};
        lv_coord_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
        lv_obj_t * grid = lv_obj_create(lv_scr_act());
        lv_obj_set_width(grid, 600);
        lv_obj_set_height(grid, 300);
        lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
        lv_obj_t * chart = lv_chart_create(grid);
        lv_chart_set_series_opa(chart, LV_OPA_70);
        lv_obj_set_width(chart, LV_SIZE_PCT(100));
        lv_obj_set_height(chart, LV_SIZE_PCT(100));
        lv_obj_set_x(chart, LV_GRID_FR(1));
        lv_obj_t * cursor = lv_obj_create(grid);
        lv_obj_set_size(cursor, 2, 200);
        lv_obj_set_x(cursor, 50);
        lv_obj_set_y(cursor, LV_GRID_FR(0.5));
        lv_obj_set_style_local_bg_color(cursor, LV_STATE_DEFAULT, LV_COLOR_BLUE);
    
        lv_chart_series_t * series = lv_chart_add_series(chart, LV_COLOR_RED);
        lv_chart_set_point_count(chart, series, 50);
        for (uint8_t i = 0; i < 50; i++) {
            lv_chart_set_next(chart, series, rand()%100);
        }
    
        lv_obj_set_event_cb(chart, chart_event_cb);
    }