zoukankan      html  css  js  c++  java
  • lvgl 库 V7版本相关应用

    笔者能力有限,如果文中出现错误的地方,还请各位朋友能够给我指出来,我将不胜感激,谢谢~

    前言

    在使用 lvgl 库的时候,笔者使用的 V7 版本的库,使用过程中发现网上关于 V7 版本的资料非常少,官网有文档介绍其如何使用,但有些方面还不是很全面,而且网上现在的中文教程大多数是针对于 V6 版本的,V6 和 V7 使用上的差异在有些方面还是挺大的,所以笔者也就想把自己在使用 V7 版本的库的时候的一些心得记录下来,这篇文章不能覆盖全面,只是笔者就最近几天所使用到的 lvgl V7 版本的一部分功能的一个总结,后期如果有新的心得了,会继续完善这个系列,好了,下面开始正文。

    V7 版本亮点

    首先,我们看一下 lvgl 的 github 仓库,可以看到有目前 V7 版的 lvgl 也有好几个版本了,最新发布的版本是 V7.1.1 的。

    github 截图

    关于 V7 版本的库相对于 V6 版本的库的一个亮点是关于 lv_core 文件夹下的 lv_obj_style_dec.h这个文件。

    image-20201108134628551

    我们先打开这个文件,可以看到这个文件全是一些宏定义以及内联函数的组合,如下所示:

    lv_obj_style_dec.h

    那为什么说这些宏定义的很巧妙呢,我们继续看下下面这样一张图:

    代码示例上图所示的代码左边是官方给出的一个 demo ,在查看代码的过程中,左图 171 行代码 go to 过去,对应的是右图的 158 行的代码,右图的代码可以看到前面全是一样的,这又是如果与作图的代码相对应的呢?这需要使用到 C 语言宏粘贴的概念。这里介绍一下羽林君公众号的一篇文章描述了宏粘贴的相关应用:你用过宏##粘贴函数,然后用函数指针查找执行吗?今天就给你说道说道,笔者也在这里简单叙述一下宏粘贴的相关概念:

    宏粘贴##的概念

    一句话概括 ## 的作用就是:将宏参数进行连接,下面看一个例子:

    #include <stdio.h>
    
    #define f(a,b) a##b
    #define g(a)  #a
    #define h(a)  g(a)
    
    int main(void)
    {
        printf("%s
    ",h(f(1,2)));
        printf("%s
    ",g(f(1,2)));
    }
    

    输出结果是这样子的:

    image-20201108151118499

    对于这个例子,需要补充的一点知识是:#的作用是将宏字符串化。下图是第一个 printf的计算过程:

    image-20201108152551380

    知道了第一个 printf 输出时的计算过程,第二个的结果也就明了了,不再进行赘述。除了可以将两个数字进行拼接,这种方法也可以用于变量的声明,在 羽林君公众号中给出的例子是这样的:

    #define def_u32_array(__name, __size)    uint32_t array_##__name[__size];
    

    那么我们可以这样进行调用:

    def_u32_array(sample_buffer, 64);
    

    宏展开的效果是这样子的:

    uint32_t array_sample_buffer[64];
    

    除此之外,也可以粘贴成函数,这也就是 lvgl V7 版本的相对于 V6 版本的一个巧妙之处。

    lvgl 的宏粘贴

    首先我们来看文件最底下这个宏定义:

    image-20201108152959668

    先将这个宏定义展开,也就是说 _LV_OBJ_STYLE_SET_GET_DECLAR等效于:_OBJ_GET_STYLE_scalar(prop_name, func_name, value_type, style_type) _OBJ_SET_STYLE_LOCAL_scalar(prop_name, func_name, value_type, style_type) _OBJ_SET_STYLE_scalar(prop_name, func_name, value_type, style_type),分析到这步还不能看出啥,我们进一步拆解,我们来看_OBJ_GET_STYLE_scalar(prop_name, func_name, value_type, style_type) ,这对应的是下图所示的代码:

    image-20201108154624174

    这个时候,再来看 _OBJ_GET_STYLE_scalar(prop_name, func_name, value_type, style_type),就是一个宏定义的内联函数,现在基本就清晰了,就是说一个 _LV_OBJ_STYLE_SET_GET_DECLARE 声明了三个函数,我们拿一个具体的例子来进行分析,我们就那这个文件的第一个声明来进行分析:

    _LV_OBJ_STYLE_SET_GET_DECLARE(RADIUS, radius, lv_style_int_t, _int, scalar)
    

    将其所有都展开,就是我们最终想要看到的内容,具体是这样子的,如下图所示:

    宏展开关系图

    再回到最开始抛出的那个问题,go to 过去为什么对应的代码是那样,也就迎刃而解了。

    V7 版本修改字体

    上述是关于宏粘贴问题的一个描述,除此之外,V7版本的库在修改字体的时候和 V6 版本的相差也是很大的,网上给出的教程以及官网给出的示例都是依据 V6 版本的,修改方法不能应用到 V7 版本上,这里指的修改字体指的是如果我想让界面显示出中文,该如何添加字库并进行应用。首先介绍的是官方给出的字体转换工具,这里所做的转换是将字体转换成 C 语言数组。

    字体转换

    这种方法存在的不好的地方是转换繁琐,需要手动操作,笔者在查找资料的时候,看到了另一款非常方便的转换工具,在这里给出 gitee 链接,https://gitee.com/WuBinCPP/MCU_Font_Release,README.md 有很详细的使用教程,使用方法不在这里赘述了,使用下来要比官网介绍的方法要方便很多。

    字体转换工具仓库截图

    那要如何将我们所转换的字体实际的用起来呢,首先要了解的是 lvgl 中的样式,样式是用来修饰对象的外观的,在 lvgl 中有对象的概念,在 lvgl 中,Button ,Label,Image,List,Chart 或者 Text area 都可以被称之为对象,如果我们现在要显示一个中文,需要做的是创建一个样式,然后,将样式的字体设置为我们要显示的中文,最后,创建一个 Label 对象,将刚刚的样样式绑定上去就可以实现了,V6 和 V7 版本关于这个方面的原理都一致,但是具体的代码相差还是有点大,关于 V6 版本的使用非常的简单,在声明了所转换的字体之后,只需要使用如下所示的语句即可:

    static lv_style_t my_style;
    lv_style_copy(&my_style,&lv_style_plain_color);//样式拷贝
    my_style.text.font = &my_font_30;//在样式中使用字体
    
    lv_obj_t* label = lv_label_create(src,NULL);//创建标签控件
    lv_label_set_style(label,LV_LABEL_STYLE_MAIN,&my_style);//设置样式
    lv_label_set_text(label,"字体使用")
    

    那在 V7 版本中该如何进行使用呢?同样的也是创建一个样式,再将样式绑定到相应的对象,最后实现字体的设置,详细的代码如下图所示:

    static lv_style_t stytle_title;
    
    lv_style_init(&style_title);
    lv_style_set_text_font(&style_title,LV_STATE_DEFAULT,&my_lv_font);
    
    lv_obj_t * title = lv_label_create(lv_scr_act(), NULL);
    lv_style_list_t * list = lv_obj_get_style_list(title, LV_LABEL_PART_MAIN);
    _lv_style_list_add_style(list, &style_title);
    lv_obj_refresh_style(title, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
    
    lv_label_set_text(title, "这是一个字体测试程序");
    

    可见两个版本的使用还是有所差异的。上述就是关于字体设置的方法,由于网络上关于如何设置 V7 版本字体提到的较少,所以在此记录一下。

    总结

    上述的内容只是关于 lvgl 的一小部分,lvgl 所有内容还是挺多的,关于 lvgl 的设计思路,还是还精妙的,其采用的对象,容器等思想,像刚刚所提到的 Button ,Label,Image,List,Chart 或者 Text area都被称之为对象,虽然对象不同,但是都可以以对象的操作方式进行操作,可以为对象添加样式属性,改变其外观。针对于所提到的容器,又可以用来放置对象,Button ,Label 等都可以放置到容器 cont 中,关于 lvgl 的内容还有很多,后期有新的心得体会了再继续分享。

    如果你觉得文章内容对你有所帮助,欢迎点赞、转发、在看三连呐~同时,也欢迎添加笔者的个人微信号,互相交流,共同进步,下面是笔者的个人微信号

    同时欢迎关注笔者的个人公众号:

  • 相关阅读:
    Oracle SQL语句大全—查看表空间
    Class to disable copy and assign constructor
    在moss上自己总结了点小经验。。高手可以飘过 转贴
    在MOSS中直接嵌入ASP.NET Page zt
    Project Web Access 2007自定义FORM验证登录实现 zt
    SharePoint Portal Server 2003 中的单一登录 zt
    vs2008 开发 MOSS 顺序工作流
    VS2008开发MOSS工作流几个需要注意的地方
    向MOSS页面中添加服务器端代码的另外一种方式 zt
    状态机工作流的 SpecialPermissions
  • 原文地址:https://www.cnblogs.com/wenziw5/p/13950617.html
Copyright © 2011-2022 走看看