lvgl图形化设计工具GUI Guider结合使用

前言

  1. 上篇博客整合了lvgl到项目中,采用的是自己编写源码的方式,实现了个简单的界面。
  2. 实际过程中一般情况开发界面都借助设计工具,这里使用的是gui guider来进行示例记录

项目结构(生成代码路径依然放到项目路径下)

在这里插入图片描述

CMakeLists配置(改为引用LVGL的源码)

file(GLOB_RECURSE EmWinSrc
        EmWin/Source/*.c
        EmWin/Resource/*.c
)


file(GLOB_RECURSE LVGL_SRC

        LVGL/Code/*.c
)

set(LVGL_INC
        LVGL/Code/custom
        LVGL/Code/generated
        LVGL/Code/generated/guider_fonts
        LVGL/Code/generated/guider_customer_fonts

)


target_sources(${PROJECT_NAME}.elf
        PRIVATE
        ${LVGL_SRC}

)

target_include_directories(${PROJECT_NAME}.elf
        PUBLIC
        ${LVGL_INC}
)

LVGL任务线程调整

在这里插入图片描述

/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-20     shchl   first version
 */
#include "includes.h"
#include "lv_api_map.h"



#if 1

#define APP_TASK_GUI_LVGL_PRIO 15
#define APP_TASK_GUI_LVGL_STK_SIZE 4096


/*
*******************************************************************************************************
*                               外部引入变量
*******************************************************************************************************
*/

/*
*******************************************************************************************************
*                               变量
*******************************************************************************************************
*/
TX_THREAD gui_lvgl_thread;
VOID *gui_thread_stack_area;
/*
*********************************************************************************************************
*                                       静态全局变量
*********************************************************************************************************
*/



/*
*********************************************************************************************************
*                                      函数声明
*********************************************************************************************************
*/
static VOID gui_lvgl_thread_entry(ULONG input);

/*
*********************************************************************************************************
*                                      外部函数
*********************************************************************************************************
*/
/**
 * @brief cpu 状态任务
 * @param first_thread 第一个启动的任务线程首地址
 */
int tx_task_gui_lvgl_create() {
    UINT status;
    gui_thread_stack_area = app_malloc(APP_TASK_GUI_LVGL_STK_SIZE);

    if(!gui_thread_stack_area){

        tx_printf("app malloc error\r\n");
        return -1;
    }

    status = tx_thread_create(&gui_lvgl_thread,              /* 任务控制块地址 */
                              "gui lvgl thread",               /* 任务名 */
                              gui_lvgl_thread_entry,                  /* 启动任务函数地址 */
                              0,                             /* 传递给任务的参数 */
                              gui_thread_stack_area,            /* 堆栈基地址 */
                              APP_TASK_GUI_LVGL_STK_SIZE,    /* 堆栈空间大小 */
                              APP_TASK_GUI_LVGL_PRIO,        /* 任务优先级*/
                              APP_TASK_GUI_LVGL_PRIO,        /* 任务抢占阀值 */
                              TX_NO_TIME_SLICE,               /* 不开启时间片 */
                              TX_AUTO_START);                 /* 创建后立即启动 */
    if (status) {
        tx_printf("create error:%d\r\n",status);
    }

    return TX_SUCCESS;
}

TX_THREAD_EXPORT(tx_task_gui_lvgl_create);

/*
*********************************************************************************************************
*                                      内部函数
*********************************************************************************************************
*/
#include "gui_guider.h"
#include "events_init.h"
lv_ui guider_ui;

static VOID gui_lvgl_thread_entry(ULONG input) {
    setup_ui(&guider_ui);
    events_init(&guider_ui);

    while (1) {
        lv_task_handler();
        tx_thread_sleep(5);
    }

}

#endif

测试界面

在这里插入图片描述

通过软件添加3个事件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

代码事件中添加日志

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

将移动代码的获取新值的回调函数替换成自己的(原有的基础上加个输出)

/*
 * Copyright 2024 NXP
 * SPDX-License-Identifier: MIT
 * The auto-generated can only be used on NXP devices
 */

#include "events_init.h"
#include <stdio.h>
#include "lvgl.h"

void events_init(lv_ui *ui) {
}

int32_t lv_anim_path_ease_in2(const lv_anim_t *a);

static void screen_1_btn_1_event_handler(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    lv_anim_t screen_1_led_1_anim_x;
    lv_anim_t screen_1_led_1_anim_y;
    switch (code) {
        case LV_EVENT_CLICKED: {
            lv_obj_set_style_bg_color(guider_ui.screen_1_spangroup_1, lv_color_make(0xd2, 0x1e, 0x1e), LV_PART_MAIN);
            lv_obj_set_pos(guider_ui.screen_1_led_1, 0, 0);

            //Write animation: screen_1_led_1move in x direction
            lv_anim_init(&screen_1_led_1_anim_x);
            lv_anim_set_var(&screen_1_led_1_anim_x, guider_ui.screen_1_led_1);
            lv_anim_set_time(&screen_1_led_1_anim_x, 10000);
            lv_anim_set_exec_cb(&screen_1_led_1_anim_x, (lv_anim_exec_xcb_t) lv_obj_set_x);
            lv_anim_set_values(&screen_1_led_1_anim_x, lv_obj_get_x(guider_ui.screen_1_led_1), 0);
            lv_anim_set_path_cb(&screen_1_led_1_anim_x, &lv_anim_path_ease_in2);
            lv_anim_start(&screen_1_led_1_anim_x);

            //Write animation: screen_1_led_1move in y direction
            lv_anim_init(&screen_1_led_1_anim_y);
            lv_anim_set_var(&screen_1_led_1_anim_y, guider_ui.screen_1_led_1);
            lv_anim_set_time(&screen_1_led_1_anim_y, 10000);
            lv_anim_set_exec_cb(&screen_1_led_1_anim_y, (lv_anim_exec_xcb_t) lv_obj_set_y);
            lv_anim_set_values(&screen_1_led_1_anim_y, lv_obj_get_y(guider_ui.screen_1_led_1), 0);
            lv_anim_set_path_cb(&screen_1_led_1_anim_y, &lv_anim_path_ease_in2);
            lv_anim_start(&screen_1_led_1_anim_y);

            logInfo("screen_1_btn_1_event_handler");
        }
            break;
        default:
            break;
    }
}


static void screen_1_btn_2_event_handler(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    lv_anim_t screen_1_led_1_anim_x;
    lv_anim_t screen_1_led_1_anim_y;
    switch (code) {
        case LV_EVENT_CLICKED: {
            lv_obj_set_pos(guider_ui.screen_1_led_1, 0, 0);

            //Write animation: screen_1_led_1move in x direction
            lv_anim_init(&screen_1_led_1_anim_x);
            lv_anim_set_var(&screen_1_led_1_anim_x, guider_ui.screen_1_led_1);
            lv_anim_set_time(&screen_1_led_1_anim_x, 10000);
            lv_anim_set_exec_cb(&screen_1_led_1_anim_x, (lv_anim_exec_xcb_t) lv_obj_set_x);
            lv_anim_set_values(&screen_1_led_1_anim_x, lv_obj_get_x(guider_ui.screen_1_led_1), 320);
            lv_anim_set_path_cb(&screen_1_led_1_anim_x, &lv_anim_path_ease_in2);
            lv_anim_start(&screen_1_led_1_anim_x);

            //Write animation: screen_1_led_1move in y direction
            lv_anim_init(&screen_1_led_1_anim_y);
            lv_anim_set_var(&screen_1_led_1_anim_y, guider_ui.screen_1_led_1);
            lv_anim_set_time(&screen_1_led_1_anim_y, 10000);
            lv_anim_set_exec_cb(&screen_1_led_1_anim_y, (lv_anim_exec_xcb_t) lv_obj_set_y);
            lv_anim_set_values(&screen_1_led_1_anim_y, lv_obj_get_y(guider_ui.screen_1_led_1), 480);
            lv_anim_set_path_cb(&screen_1_led_1_anim_y, &lv_anim_path_ease_in2);
            lv_anim_start(&screen_1_led_1_anim_y);

            tx_printf("screen_1_btn_2_event_handler\r\n");
        }
            break;
        default:
            break;
    }
}

// 自定义 lv_anim_path_ease_in
int32_t lv_anim_path_ease_in2(const lv_anim_t *a) {

    static int cnt = 0;
    if (cnt > 20) { // 刷新20次,打印一次,方便调试
        lv_coord_t x = lv_obj_get_x(guider_ui.screen_1_led_1);
        lv_coord_t y = lv_obj_get_y(guider_ui.screen_1_led_1);
        logInfo("(x,y)-->(%d,%d)", x, y);
        cnt = 0;
    } else {
        cnt += 1;
    }



    /*Calculate the current step*/
    uint32_t t = lv_map(a->act_time, 0, a->time, 0, LV_BEZIER_VAL_MAX);
    int32_t step = lv_bezier3(t, 0, 50, 100, LV_BEZIER_VAL_MAX);

    int32_t new_value;
    new_value = step * (a->end_value - a->start_value);
    new_value = new_value >> LV_BEZIER_VAL_SHIFT;
    new_value += a->start_value;

    return new_value;
}

void events_init_screen_1(lv_ui *ui) {
    lv_obj_add_event_cb(ui->screen_1_btn_1, screen_1_btn_1_event_handler, LV_EVENT_ALL, NULL);
    lv_obj_add_event_cb(ui->screen_1_btn_2, screen_1_btn_2_event_handler, LV_EVENT_ALL, NULL);
}

在这里插入图片描述

总结

  1. gui guider 基本上不做太复杂的逻辑设计,够用了。
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
lvgl nxp gui guider 1.6是一个用于NXP微控制器的图形用户界面(GUI)开发工具LVGL(轻量级嵌入式图形库)是一款开源的GUI库,可以在各种嵌入式设备上创建美观且功能丰富的用户界面。NXP GUI Guider是一个可视化的GUI设计工具,可以通过简单的拖放操作来设计和生成LVGL GUI界面。 使用LVGL NXP GUI Guider 1.6可以轻松快速地开发出专业水平的GUI界面。它提供了丰富的内置控件,如按钮、文本框、进度条、滑块等,用户可以根据自己的需求进行定制和扩展。此外,它还支持动画效果、多语言支持和主题切换等功能,使得界面更加丰富多样。 利用该工具,开发人员只需通过简单的拖放操作就可以设计和布局界面元素,并直接在编辑器中进行预览和调试。同时,可以通过代码生成器自动生成所需的LVGL C代码,方便集成进项目中。这样,开发人员可以更专注于业务逻辑或者其他核心功能的实现,提高开发效率。 此外,LVGL NXP GUI Guider 1.6还支持与其他开发工具的集成,如NXP MCUXpresso IDE和RTCS库等。这样,开发者可以在一个完整的开发环境中进行GUI开发,并且可以更好地与其他系统组件进行集成和交互。 总之,LVGL NXP GUI Guider 1.6是一个强大且易用的GUI开发工具,能够帮助开发者快速创建出高效、美观的GUI界面,并且与NXP微控制器的生态系统完美集成,提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

詩不诉卿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值