关于LVGL换页问题

        在网上没有找到有耐心去看的适合的教程和视频,主要是我写的代码实在是太多,虽然只是几页非常简洁的页面,但是改动起来还是嫌麻烦,所以完全没有耐心。在寻找的路上挣扎了很长一段时间,2024年9月27日晚偶然在网上看到一个比较简单而且看得懂的例子,于是复制了下来做实验,没想到成功了,但是没能匹配到我原来的代码上就被叫去打台球了,于是今天2024年9月28日早上上完课,在机房大约实验了快2个小时,还是被一堆问题所难倒,于是就去吃了饭交网费了,大约15:00:36来到教室到19:19:24,终于得到解决,可能是一种最低级的解决办法。

        问题所在:关于LVGL中实时更新数据而且在换页后停止更新的问题。解决的办法:找到一个比较简洁的计时器代码,一点一点试,差点放弃,同时想过很多种可能。解决的问题:在需要更新的页面air_display()函数中后面加了while(1),

while (1)
   {
        if(display_btn_left && display_btn_right)
        {
                lv_task_handler();  //回调函数(需要更新的内容)
        }else{
            break;      //如果触发了显示界面其中一个将会跳出该循环
        }
    }


并且在air_display()函数的回调函数display_even_cb()里面,触发temp按钮代码的下面加了生成一个定时器的代码:

timer = lv_timer_create(timer_callback, 1000, NULL);

         实现在点temp时生成计时器,并且有效的执行计时器回调函数更新数据。开启定时器后,在切换页面后还是需要关闭一下,因为不关闭,会占用LVGL很多资源,导致无法运行新的页面;为了解决这个问题,于是在home_page()和pre_waring()两个函数里面加了判定标准display_btn_left 和 display_btn_right,以此来准确的删除定时器。这个问题应该肯定有比较好的就解决方法的,我这种方法应该是最烂的一种。还有一个不得不说的问题,也就是存在的bug,想要点击home和waring按钮必须先生成一个计时器,也就是先点击temp按钮,不然将会卡死,出现这一问题的原因是:home_page()和pre_waring()要删除计时器而又灭有计时器可删的,本来计时器timer是一个指针,容易出现问题。


 
#include "aqi_lvgl.h"
#include "lvgl.h"

static lv_obj_t *btn[8]; //
static lv_obj_t *aqi[8];

static lv_obj_t *obj_waring[8];  //
static lv_obj_t *waring_up[8];  //用于设置预警值的加操作
static lv_obj_t *waring_down[8];//用于设置预警值的减操作
static lv_obj_t *waring_up_key[8];
static lv_obj_t *waring_down_key[8];

static lv_obj_t *air_waring[8];
static int waring_value[8]={0};
static lv_obj_t *switch_waring[8];
static int switch_state[8]={0};

static int air_value[8]={0};
static char air[8][6]={"PM2.5","PM10","SO2","NO2","CO","O3","AQI","TEMP"};

static lv_obj_t *redirct[6];   //跳转
static lv_obj_t *redirct_value[6]; //跳转的方向

static bool display_btn_left=true;      //显示页面的左右按键转态值
static bool display_btn_right=true;     //true表示在现实界面,false表示离开现实界面

void pre_warning(void);
void air_dispaly(void);
void home_page(void);

static  lv_timer_t * timer;          创建一个定时器,调用 timer_callback 每 1000 毫秒 (1 秒)


// 定时器回调
static void timer_callback(lv_timer_t * timer)
{
    for(int i=0;i<8;i++)    //显示空气值
    {

        if(i!=7)
        {
            air_value[i]++;
            lv_label_set_text_fmt(aqi[i],"%s \n\n %d ug/m^3",air[i],air_value[i]);
            //printf("%s \n\n %d ug/m^3",air[i],air_value[i]);
            
             当设的阈值小于空气因子值时,显示页面变为红色
            if(waring_value[i] < air_value[i]&&switch_state[i]) //当设的阈值小于空气因子值时,显示页面变为红色
            {
               lv_obj_set_style_bg_color(btn[i],lv_color_hex(0xE70000),LV_STATE_DEFAULT);
            }
            
        }else{
            lv_label_set_text_fmt(aqi[i],"%s",air[i]);
        }
    }
    // 这里可以执行其他任务,例如更新 UI
}

//显示回调
static void display_even_cb(lv_event_t *e)
{
    lv_obj_t *target = lv_event_get_target(e);
    
//    当设的阈值小于空气因子值时,显示页面变为红色
//    for(int i=0;i<7;i++)
//    {
//        if(waring_value[i] < air_value[i]&&switch_state[i]) //当设的阈值小于空气因子值时,显示页面变为红色
//        {
//           lv_obj_set_style_bg_color(btn[i],lv_color_hex(0xE70000),LV_STATE_DEFAULT);
//        }
//    }
    
    //按下显示页面的TEMP按键时,清空显示页面的所有值,并且开启定时器,更新数据;
    if(target == btn[7])  //按下显示页面的TEMP按键时,清空显示页面的所有值
    {
        for(int i=0;i<7;i++)
        {
            air_value[i]=0;
            lv_label_set_text_fmt(aqi[i],"%s \n\n %d ug/m^3",air[i],air_value[i]);
            lv_obj_set_style_bg_color(btn[i],lv_color_hex(0x2094F0),LV_STATE_DEFAULT);
        }
        timer = lv_timer_create(timer_callback, 1000, NULL);    //当按下temp按钮时,将开启一个计时器
    }

}

//警告显示回调
static void waring_event_cb(lv_event_t *e)
{
    lv_obj_t *target = lv_event_get_target(e);
    for(int i=0;i<7;i++)
    {
        if(target == waring_up[i])
        {
            waring_value[i]++;
            lv_label_set_text_fmt(air_waring[i],"%s : %d",air[i],waring_value[i]);
        }else if(target == waring_down[i])
        {
            waring_value[i]--;
            lv_label_set_text_fmt(air_waring[i],"%s : %d",air[i],waring_value[i]);
        }else if(target == switch_waring[i])
        {
            switch_state[i]++;
            if(switch_state[i] > 1) //大于1表示第二次按下,也就是关闭状态,因为默认开机为关闭状态
            {
                switch_state[i]=0;
            }
        }
    }
    if(target == waring_up[7])
    {
        for(int i=0;i<7;i++)
        {
            waring_value[i]++;
            lv_label_set_text_fmt(air_waring[i],"%s : %d",air[i],waring_value[i]);
        }

    }else if(target == waring_down[7])
    {
        for(int i=0;i<7;i++)
        {
            waring_value[i]--;
            lv_label_set_text_fmt(air_waring[i],"%s : %d",air[i],waring_value[i]);
        }

    }else if(target == switch_waring[7])   //关闭所有开关和开启所有开光
    {
        switch_state[7]++;
        if(switch_state[7] > 1) //大于1表示第二次按下,也就是关闭状态,因为默认开机为关闭状态
        {
            switch_state[7]=0;
            for(int i=0;i<8;i++)
            {
                switch_state[i]=0;
                lv_obj_clear_state(switch_waring[i],LV_STATE_CHECKED);   //关闭开关
            }

        }else
        {
            for(int i=0;i<8;i++)
            {
                switch_state[i]=1;
                lv_obj_add_state(switch_waring[i],LV_STATE_CHECKED);    //开启开关
            }
        }

    }

}

//换页选择回调
static void redirct_event_cb(lv_event_t *e)
{
    lv_obj_t *target =  lv_event_get_target(e);
    if(target == redirct[0] || target == redirct[3])
    {
        lv_obj_clean(lv_scr_act());     //清除当前活动屏幕上面的所有对象
       if(target == redirct[3])
       {
           display_btn_right = false;
       }
       pre_warning();

    }else if(target == redirct[1] || target == redirct[4])
    {
        lv_obj_clean(lv_scr_act());     //清除当前活动屏幕上面的所有对象
        air_dispaly();                  //显示显示页
        display_btn_left = true;        //
        display_btn_right = true;       //
        
    }else if(target == redirct[2] || target == redirct[5])
    {
        lv_obj_clean(lv_scr_act());
        if(target == redirct[2])
        {
            display_btn_left = false;
        }
        home_page();
    }
}


//换页设置函数
void redirct_set(int i)
{
    redirct[i] = lv_btn_create(lv_scr_act());
    lv_obj_set_size(redirct[i],80,45);
    lv_obj_set_style_bg_color(redirct[i],lv_color_hex(0xF0F0F0),LV_STATE_DEFAULT);
    lv_obj_set_style_opa(redirct[i],200,LV_STATE_DEFAULT);
    if(i%2==0)
    {
        lv_obj_align(redirct[i],LV_ALIGN_TOP_LEFT,30,20);
    }else{
        lv_obj_align(redirct[i],LV_ALIGN_TOP_RIGHT,-30,20);
    }
    lv_obj_add_event_cb(redirct[i],redirct_event_cb,LV_EVENT_CLICKED,NULL);    //触发回调

    redirct_value[i]=lv_label_create(redirct[i]);
    lv_obj_set_style_text_color(redirct_value[i],lv_color_hex(0xE70000),LV_STATE_DEFAULT);
    lv_obj_set_align(redirct_value[i],LV_ALIGN_CENTER);
    lv_obj_set_style_text_font(redirct_value[i],&lv_font_montserrat_16,LV_STATE_DEFAULT);

}

//警告函数
void pre_warning(void)
{
    //判断是否需要清理显示界面的定时器
    if((display_btn_left && !display_btn_right) || (display_btn_left && display_btn_right))
    {
        lv_timer_del(timer);
    }
    
    lv_obj_t *title = lv_label_create(lv_scr_act());
    lv_label_set_text(title,"WARING PAGE");
    lv_obj_set_style_text_font(title,&lv_font_montserrat_24,LV_STATE_DEFAULT);
    lv_obj_align(title,LV_ALIGN_TOP_MID,0,35);


    for(int i=0;i<8;i++)
    {
        obj_waring[i] = lv_obj_create(lv_scr_act());
        lv_obj_set_size(obj_waring[i],150,150);

        waring_up[i] = lv_btn_create(obj_waring[i]);
        lv_obj_align(waring_up[i],LV_ALIGN_TOP_MID,-30,0);
        lv_obj_set_style_bg_color(waring_up[i],lv_color_hex(0xE0E0E0),LV_STATE_DEFAULT);
        lv_obj_add_event_cb(waring_up[i],waring_event_cb,LV_EVENT_CLICKED,NULL);
        waring_down[i] = lv_btn_create(obj_waring[i]);
        lv_obj_align(waring_down[i],LV_ALIGN_TOP_MID,30,0);
        lv_obj_set_style_bg_color(waring_down[i],lv_color_hex(0xE0E0E0),LV_STATE_DEFAULT);
        lv_obj_add_event_cb(waring_down[i],waring_event_cb,LV_EVENT_CLICKED,NULL);     //触发回调函数

        waring_up_key[i] = lv_label_create(waring_up[i]);
        lv_label_set_text(waring_up_key[i],"+");
        lv_obj_set_align(waring_up_key[i],LV_ALIGN_CENTER);
        lv_obj_set_style_text_color(waring_up_key[i],lv_color_hex(0x2094F0),LV_STATE_DEFAULT);
        waring_down_key[i] = lv_label_create(waring_down[i]);
        lv_label_set_text(waring_down_key[i],"-");
        lv_obj_set_align(waring_down_key[i],LV_ALIGN_CENTER);
        lv_obj_set_style_text_color(waring_down_key[i],lv_color_hex(0x2094F0),LV_STATE_DEFAULT);

        air_waring[i] = lv_label_create(obj_waring[i]);
        lv_obj_align(air_waring[i],LV_ALIGN_CENTER,0,0);
        if(i == 7)
        {
            lv_label_set_text_fmt(air_waring[i],"%s",air[i]);
        }else
        {
            lv_label_set_text_fmt(air_waring[i],"%s : %d",air[i],waring_value[i]);
        }


        switch_waring[i] = lv_switch_create(obj_waring[i]);
        lv_obj_align_to(switch_waring[i],air_waring[i],LV_ALIGN_OUT_BOTTOM_MID,0,15);
        lv_obj_add_event_cb(switch_waring[i],waring_event_cb,LV_EVENT_CLICKED,NULL);        //触发回调函数

        if(i==0)
        {
            lv_obj_align(obj_waring[i],LV_ALIGN_TOP_LEFT,55,85);
        }else if(i<4)
                {
                    lv_obj_align_to(obj_waring[i],obj_waring[i-1],LV_ALIGN_OUT_RIGHT_MID,30,0);
                }
                else{
                    lv_obj_align_to(obj_waring[i],obj_waring[i-4],LV_ALIGN_OUT_BOTTOM_MID,0,20);
                }
    }

    for(int i=0;i<8;i++)
    {
        if(switch_state[i]==0)          //跳转后,如果状态为0表示之前为关闭状态,反之为开启状态
        {
            lv_obj_clear_state(switch_waring[i],LV_STATE_CHECKED);
        }else {
            lv_obj_add_state(switch_waring[i],LV_STATE_CHECKED);
        }
    }

    redirct_set(4);
    redirct_set(5);
    lv_label_set_text(redirct_value[4],"display");
    lv_label_set_text(redirct_value[5],"home");
}

//空气质量值显示函数
void air_dispaly(void)
{
    lv_obj_t *title = lv_label_create(lv_scr_act());
    lv_label_set_text(title,"DISPLAY PAGE");
    lv_obj_set_style_text_font(title,&lv_font_montserrat_24,LV_STATE_DEFAULT);
    lv_obj_align(title,LV_ALIGN_TOP_MID,0,50);
    //Model_AirValue();//模拟空气值
    
    //显示基本的图形框架
    for(int i=0;i<8;i++)
    {
        btn[i] = lv_btn_create(lv_scr_act());
        lv_obj_set_size(btn[i],130,110);
        if(i == 0)
        {
            lv_obj_align(btn[i],LV_ALIGN_DEFAULT,50,125);
        }else if(i<4)
                {
                    lv_obj_align_to(btn[i],btn[i-1],LV_ALIGN_OUT_RIGHT_MID,60,0);
                }else{
                    lv_obj_align_to(btn[i],btn[i-4],LV_ALIGN_OUT_BOTTOM_MID,0,60);
                }

        if(i==7)
        {
            lv_obj_set_style_bg_color(btn[i],lv_color_hex(0xCA3316),LV_STATE_DEFAULT);
        }

        lv_obj_add_event_cb(btn[i],display_even_cb,LV_EVENT_CLICKED,NULL);

        aqi[i] = lv_label_create(btn[i]);
         lv_obj_set_align(aqi[i],LV_ALIGN_CENTER);
    }
    
    //跳转显示按钮
    redirct_set(2);
    redirct_set(3);
    lv_label_set_text(redirct_value[2],"home");
    lv_label_set_text(redirct_value[3],"waring");
    
    //初始化空气值
    for(int i=0;i<7;i++)
    {
       lv_label_set_text_fmt(aqi[i],"%s \n\n %d ug/m^3",air[i],0);
    }
    
    // 创建一个定时器,调用 timer_callback 每 1000 毫秒 (1 秒)
    //timer = lv_timer_create(timer_callback, 1000, NULL);
    while (1)
   {

        if(display_btn_left && display_btn_right)
        {
            //lv_timer_resume(timer);
            //lv_tick_inc(5); // LVGL tick
            lv_task_handler();  //回调函数(需要更新的内容)
        }else{
            //lv_timer_pause(timer);      //暂停定时器
            break;      //如果触发了显示界面其中一个将会跳出该循环
        }
    }
    
    
}


//主页显示函数
void home_page(void)
{
    //判断是否需要清理显示界面的定时器
    if((!display_btn_left && display_btn_right) || (display_btn_left && display_btn_right))
    {
        lv_timer_del(timer);
    }
    
    lv_obj_t *homepage = lv_label_create(lv_scr_act());
    lv_label_set_text(homepage,"#E70000 AIR QUALITY MONITORING SYSTEM\n #"
                      "Real-ti me air quality monitoring, safeguarding your breathing health.\n"
                      "Clearly displaying data such as PM2.5 and PM10, keeping fresh air within your grasp.\n");
    lv_label_set_recolor(homepage,true);
    lv_obj_align(homepage,LV_ALIGN_CENTER,0,-40);
    lv_obj_set_style_text_font(homepage,&lv_font_montserrat_18,LV_STATE_DEFAULT);
    lv_obj_set_style_text_align(homepage,LV_TEXT_ALIGN_CENTER,LV_STATE_DEFAULT);

    redirct_set(0);
    redirct_set(1);
    lv_label_set_text(redirct_value[0],"waring");
    lv_label_set_text(redirct_value[1],"display");

}


//调用主函数
void aqi_lvgl(void)
{
    air_dispaly();    //第一页

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值