嵌入式图形界面库lvgl使用详解
嵌入式图形界面库lvgl使用详解
前言
本文相当一个快速入门的lvgl学习教程,主要记录了lvgl在vscode开发环境的配置,以及相关的环境配置,最后通过实例熟悉lvgl的使用。
下面主要参考了lvgl中文文档,还有一个优秀博主的系列博文。
(一)lvgl ubuntu环境vscode模拟器安装配置
一开始接触lvgl时,lvgl版本已经更新到了8.0了,但网上的教程大多数时7.11的,在配置vscode lvgl模拟器开发环境lv_sim_vscode_sdl的时候遇到了些麻烦。
1.首先,github在国内访问速度极慢,直接git clone几乎失效,
2.lv_examples是对应lvgl 7.11的,当前lvgl 8.0对应的lv_examples已经改名为了lv_demos,git clone下来的也是lv_demos.
3.lv_drivers,lvgl需要自己现在配置
我把配置好的lv_sim_vscode_sdl的项目配置好后,直接发布在到了gitee上。
下面是安装过程。
//安装sdl
sudo apt-get update && sudo apt-get install -y build-essential libsdl2-dev
//git clone 项目
git clone https://gitee.com/lingcb/lv_sim_vscode_sdl-7.11.0.git
当环境安装了vscode时,双击文件simulator.code-workspace,打开项目。若打不开,直接使用vscode打开文件夹。
(二)lvgl lv_conf.h环境配置
lv_conf.h文件里可以设置屏幕的大小
下面的具体变量
#define LV_HOR_RES_MAX (240)
#define LV_VER_RES_MAX (320)
需要注意的点是,若项目编译运行了,生成了build文件夹,需要删除 build文件夹,再重新按F5重新运行,在lv_conf.h上的配置才生效。
之后的运行几个经典的例子,可以参考这篇博文后面部分。
(三)lvgl 控件使用的几个例子
这里给几个使用的例子。
(1)bar.h
创建一个文件“bar.h”,在上面的项目里的“main.c”,导入下面的bar.h代码。根据图片的位置上添加直接运行,便可。后续的几个控件的运行,基本差不多。
//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/03_bar.html
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
//定义控件,及相关事件
static void bar()
{
lv_obj_t * bar1 = lv_bar_create(lv_scr_act(), NULL);
lv_obj_set_size(bar1, 200, 20);
lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0);
lv_bar_set_anim_time(bar1, 20000);
lv_bar_set_value(bar1, 100, LV_ANIM_ON);
}
(2)button.h
//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/04_btn.html
//导入lvgl载入h文件
#include <stdio.h>
#include "../lvgl/lvgl.h"
//定义控件,及相关事件
static void event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_CLICKED) {
printf("Clicked\n");
}
else if(event == LV_EVENT_VALUE_CHANGED) {
printf("Toggled\n");
}
}
static void button()
{
lv_obj_t * label;
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_event_cb(btn1, event_handler);
lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40);
label = lv_label_create(btn1, NULL);
lv_label_set_text(label, "Button");
lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_event_cb(btn2, event_handler);
lv_obj_align(btn2, NULL, LV_ALIGN_CENTER, 0, 40);
lv_btn_set_checkable(btn2, true);
lv_btn_toggle(btn2);
lv_btn_set_fit2(btn2, LV_FIT_NONE, LV_FIT_TIGHT);
label = lv_label_create(btn2, NULL);
lv_label_set_text(label, "Toggled");
}
(3)image.h
//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/14_img.html
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
//定义控件,及相关事件
#define SLIDER_WIDTH 20
static void create_sliders(void);
static void slider_event_cb(lv_obj_t * slider, lv_event_t event);
static lv_obj_t * red_slider, * green_slider, * blue_slider, * intense_slider;
static lv_obj_t * img1;
LV_IMG_DECLARE(img_cogwheel_argb);
static void slider_event_cb(lv_obj_t * slider, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
/* Recolor the image based on the sliders' values */
lv_color_t color = lv_color_make(lv_slider_get_value(red_slider), lv_slider_get_value(green_slider), lv_slider_get_value(blue_slider));
lv_opa_t intense = lv_slider_get_value(intense_slider);
lv_obj_set_style_local_image_recolor_opa(img1, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, intense);
lv_obj_set_style_local_image_recolor(img1, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, color);
}
}
static void create_sliders(void)
{
/* Create a set of RGB sliders */
/* Use the red one as a base for all the settings */
red_slider = lv_slider_create(lv_scr_act(), NULL);
lv_slider_set_range(red_slider, 0, 255);
lv_obj_set_size(red_slider, SLIDER_WIDTH, 200); /* Be sure it's a vertical slider */
lv_obj_set_style_local_bg_color(red_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_obj_set_event_cb(red_slider, slider_event_cb);
/* Copy it for the other three sliders */
green_slider = lv_slider_create(lv_scr_act(), red_slider);
lv_obj_set_style_local_bg_color(green_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_LIME);
blue_slider = lv_slider_create(lv_scr_act(), red_slider);
lv_obj_set_style_local_bg_color(blue_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE);
intense_slider = lv_slider_create(lv_scr_act(), red_slider);
lv_obj_set_style_local_bg_color(intense_slider, LV_SLIDER_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_GRAY);
lv_slider_set_value(intense_slider, 255, LV_ANIM_OFF);
lv_obj_align(red_slider, NULL, LV_ALIGN_IN_LEFT_MID, 20, 0);
lv_obj_align(green_slider, red_slider, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
lv_obj_align(blue_slider, green_slider, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
lv_obj_align(intense_slider, blue_slider, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
}
static void image(void){
create_sliders();
/* Now create the actual image */
img1 = lv_img_create(lv_scr_act(), NULL);
lv_img_set_src(img1, &img_cogwheel_argb);
lv_obj_align(img1, NULL, LV_ALIGN_IN_RIGHT_MID, -20, 0);
}
(4)label.h
//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/17_label.html
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
//定义控件,及相关事件
static void label()
{
lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK); /*Break the long lines*/
lv_label_set_recolor(label1, true); /*Enable re-coloring by commands in the text*/
lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER); /*Center aligned lines*/
lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label "
"and wrap long text automatically.");
lv_obj_set_width(label1, 150);
lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);
lv_obj_t * label2 = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(label2, LV_LABEL_LONG_SROLL_CIRC); /*Circular scroll*/
lv_obj_set_width(label2, 150);
lv_label_set_text(label2, "It is a circularly scrolling text. ");
lv_obj_align(label2, NULL, LV_ALIGN_CENTER, 0, 30);
}
(5)switch.h
//参考:http://lvgl.100ask.org/7.11/documentation/04_widgets/29_switch.html
//导入lvgl载入h文件
#include <stdio.h>
#include "../lvgl/lvgl.h"
//定义控件,及相关事件
static void switch_event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
printf("State: %s\n", lv_switch_get_state(obj) ? "On" : "Off");
}
}
static void _switch()
{
lv_obj_t *sw1 = lv_switch_create(lv_scr_act(), NULL);
lv_obj_align(sw1, NULL, LV_ALIGN_CENTER, 0, -50);
lv_obj_set_event_cb(sw1, switch_event_handler);
/*Copy the first switch and turn it ON*/
lv_obj_t *sw2 = lv_switch_create(lv_scr_act(), sw1);
lv_switch_on(sw2, LV_ANIM_ON);
lv_obj_align(sw2, NULL, LV_ALIGN_CENTER, 0, 50);
}
(四)lvgl 任务(task)使用
lvgl task添加后,可以自动定时运行。
使用方法依旧如上。
//参考:https://blog.csdn.net/weixin_41572450/article/details/111546117
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
//basic variables
uint8_t test_data = 0;
lv_obj_t * label1;
//define label
static void task_label()
{
label1 = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK); /*Break the long lines*/
lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER); /*Center aligned lines*/
lv_label_set_text(label1, "Hello World!");
lv_obj_set_width(label1, 150);
lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);
}
//callback function
static void task_cb(lv_task_t* task)
{
uint8_t *user_data = (uint8_t*)task->user_data;
(*user_data)++;
lv_label_set_text_fmt(label1, "Value: %d", *user_data);
}
//creat a task
void task(void)
{
task_label();
lv_task_t * t = lv_task_create(task_cb,1000,LV_TASK_PRIO_MID, &test_data);
}
(五)lvgl 图片(使用)
lvgl 可以通过C array导入图片显示,下面是一个使用图片的例子。imgs/backgroud.h lvgl官方提供的在线转换器转换而来,当图片上传,转换的结果格式是.c的,下载来后修改格式为.h就可以直接导入了。需要注意一点:当上传图片后,会出现File name(s)这选项,里面提前命名好,后面的引用会直接用到。
//参考:https://blog.csdn.net/weixin_41572450/article/details/111546117
//导入lvgl载入h文件
#include "../lvgl/lvgl.h"
#include "imgs/backgroud.h"
//basic variables
uint8_t pos_data = 0;
lv_obj_t * pos_label;
//define label
static void posxyz_label()
{
//setting backgroud
//LV_IMG_DECLARE(backgroud_map);
img1 = lv_img_create(lv_scr_act(), NULL);
lv_img_set_auto_size(img1, true);
lv_img_set_src(img1, &backgroud);
lv_obj_align(img1, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0);
//setting label
pos_label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(pos_label, LV_LABEL_LONG_BREAK); /*Break the long lines*/
lv_label_set_align(pos_label, LV_LABEL_ALIGN_CENTER); /*Center aligned lines*/
// set font size
static lv_style_t font_style;
lv_style_init(&font_style);
lv_style_set_text_font(&font_style, LV_STATE_DEFAULT, &lv_font_montserrat_30);
lv_obj_add_style(pos_label,LV_LABEL_PART_MAIN, &font_style);
//setting basic
lv_label_set_text(pos_label, "\nStart");
lv_obj_set_width(pos_label, 150);
lv_obj_align(pos_label, NULL, LV_ALIGN_CENTER, 0, -30);
}
//callback function
static void pos_task_cb(lv_task_t* task)
{
uint8_t *user_data = (uint8_t*)task->user_data;
(*user_data)++;
uint8_t x;
uint8_t y;
uint8_t z;
if (*user_data>=9999){
*user_data=0;
}
x = ((*user_data)%1000)/100;
y = ((*user_data)%100)/10;
z = ((*user_data)%10);
lv_label_set_text_fmt(pos_label, "\n%d,%d,%d", x,y,z);
}
//creat a task
void pos_task(void)
{
posxyz_label();
lv_task_t * t = lv_task_create(pos_task_cb,100,LV_TASK_PRIO_MID, &pos_data);
}
更多推荐
所有评论(0)