ESP32使用Squareline Studio生成LVGL多页面,并使用实体按键多个group切换控制多页面

  • 1.目标

        以前手搓过LVGL多页面使用实体按键的代码,由于keypad需要使用到group将按键都绑定好,因此若将多个页面的按键都绑定在一个group上,然后按键按下使得页面切换后,lvgl仍然聚焦在之前页面的按键上,而不是聚焦到新页面的按键上,再次按下就会重复此按键的效果导致不正常,之前的做法是每次切换页面将group清空,再将新页面的按键都绑定到group中,这无疑非常麻烦。为此使用多个group来控制切换页面可以很方便,但Squareline Studio生成的代码不包含group的内容,因此需要修改一下。

  • 2.Squareline Studio生成页面

        先使用Squareline Studio生成两个简单的页面,再给按键加上页面切换的事件。

  • 3.ESP-IDF修改代码

        将Squareline Studio生成的代码丢到components中当做组件,并如下修改CMakeLists。

file(GLOB FONT_SOURCES "fonts/*.c")
file(GLOB IMAGE_SOURCES "images/*.c")
file(GLOB SCREEN_SOURCES "screens/*.c")

idf_component_register(SRCS "ui.c" "ui_helpers.c" ${FONT_SOURCES} ${IMAGE_SOURCES} ${SCREEN_SOURCES}
                        INCLUDE_DIRS "."
                        REQUIRES lvgl)

         将lvgl,按键以及ui初始化完成。

            接着,在ui.h中添加如下代码,分别是两个group以及一个keypad结构体。

    lv_group_t *group;
    lv_group_t *group1;
    extern lv_indev_t *indev_keypad;

             接着,在ui_Screen1_screen_init的末尾添加如下5行代码,创建group,将页面1的三个按键绑定到group,并将keypad与group绑定。

             ui_Screen2_screen_init中同理,但不需要绑定keypad与group1。

             最后,在ui.c生成的切换页面函数中添加切换页面后更改group的代码lv_indev_set_group即可。

    <think>我们正在讨论的是SquareLinesStudio(简称SLS)中的动画播放功能触发方式。根据用户问题,他/她想了解如何通过事件来触发播放动画功能。在SLS中,动画通常是在GUI设计器中创建的,然后可以通过代码或事件来触发播放。常见的事件包括按钮点击、定时器到期、或者其他用户交互事件。步骤:1.在GUI设计器中创建动画(例如,给一个对象设置关键帧动画)。2.在事件处理代码中,获取该动画对象调用播放方法。假设我们有一个动画对象,名为"anim1",我们可以通过以下方式在事件中触发:例如,通过按钮点击事件触发:-在GUI设计器中,我们有一个按钮和一个动画(比如是一个矩形的移动动画)。-我们给按钮添加一个点击事件的处理函数,在该函数中调用动画的播放方法。在SLS的代码编辑器中,我们可以这样写(以MicroPython为例,因为SLS通常使用MicroPython):```pythondefon_button_clicked(event):#获取动画对象,假设动画名称为"anim1"anim1=lv.anim.__cast__(lv.scr_act().get_child(0).get_child(0))#这里只是示例获取方式,实际应根据动画对象的具体位置获取#更直接的方式是,如果我们知道动画对象的名称,我们可以通过对象树查找,但SLS中可能提供更直接的方法#实际上,在SLS中,我们通常会在设计时给对象命名,然后通过名称获取对象#假设我们给动画对象命名为"anim_obj",那么我们可以这样获取:anim_obj=lv.scr_act().get_child_by_name("anim_obj")#然后播放动画anim_obj.play()```但是,需要注意的是,在SLS中,动画对象可能不是直接作为一个独立的对象存在,而是作为对象的一个属性。更常见的做法是,我们给一个对象(比如一个矩形)添加动画,然后我们通过该对象来播放动画。例如,我们给一个矩形(名为"rect1")添加了一个动画,那么我们可以这样触发:```pythondefon_button_clicked(event):rect1=lv.scr_act().get_child_by_name("rect1")#假设我们给这个矩形添加的动画存储在它的一个属性中,但通常我们会在设计时创建动画,然后动画会自动关联到对象#在SLS中,我们通常通过动画组(lv.anim_t)来控制,但播放动画的方法可能是直接调用动画的start,或者通过对象的方法。#实际上,在SLS中,我们更推荐使用以下方式:#在设计时,我们创建了一个动画,设置了它的自动播放为false,然后我们在事件中启动它。#如何创建动画设置不自动播放?在GUI设计器的动画属性中,有一个“自动播放”选项,取消勾选。#然后在代码中,我们可以这样:#首先,我们需要获取动画对象。在SLS中,每个动画也可以被命名,我们可以通过名称获取动画。#假设我们的动画命名为"my_anim",那么我们可以这样获取:my_anim=lv.anim.get_by_name("my_anim")#注意:这个API可能需要确认是否存在,或者SLS可能有自己的封装#如果SLS没有提供直接通过名称获取动画的API,那么我们可以将动画对象保存在一个全局变量中,然后在事件中引用。#在GUI设计器中,我们可以将动画对象赋值给一个全局变量(在初始化代码中):#例如,在屏幕初始化时:#globalanim1#anim1=lv.anim.create()#这里只是示例,实际在SLS中创建动画的方式可能不同#但是,SLS通常会在生成代码时,将动画对象以特定名称的变量存在,我们可以直接使用该变量。#例如,如果我们在设计器中创建了一个名为"anim1"的动画,那么在生成的代码中,会有一个名为anim1的变量。#因此,在事件处理函数中,我们可以直接使用这个变量:anim1.play()#假设设计器生成的动画变量名为anim1#如果动画变量在事件处理函数的作用域内不可见,我们可以将其设置为全局变量,或者通过其他方式获取。#总结:在SLS中,最简便的方式是在设计器中将动画设置为不自动播放,然后在事件处理函数中直接调用设计器生成的动画变量(如anim1)的play方法。```因此,具体步骤为:1.在GUI设计器中创建动画,取消“自动播放”选项(这样动画不会在加载时自动播放)。2.给动画对象命名(比如命名为"anim1"),或者记住设计器生成的动画变量名(通常和对象名相同)。3.在需要触发的事件(如按钮点击)的处理函数中,调用该动画的play方法。示例代码(假设动画变量名为anim1):```pythondefon_button_clicked(event):anim1.play()```注意:如果动画已经播放过,需要重新播放,可能需要先停止动画重置状态,或者设置动画可以重复播放。另外,SLS也支持通过时间轴(timeline)来管理多个动画,但用户问题只要求播放一个动画。如果用户有多个动画需要同时播放,可以考虑使用时间轴。引用说明:SquareLinesStudio的文档中提到了动画的创建和事件触发方法[^1]。为了更清晰地说明,我们总结为以下步骤:步骤1:在GUI设计器中创建动画(例如,选择一个对象,然后在动画属性面板中创建关键帧动画)。步骤2:设置该动画的“自动播放”为false。步骤3:给动画命名(例如“anim1”),这样在代码中可以直接使用这个名称的变量。步骤4:在事件处理函数(如按钮的点击事件)中,调用`anim1.play()`。如果用户不清楚如何创建动画,可以查阅SLS的动画教程。相关问题:1.如何在SquareLinesStudio中创建关键帧动画?2.如何设置动画的循环播放?3.如何同时播放多个动画?4.如何停止一个正在播放的动画?</think>在SquareLines Studio中,通过事件触发播放动画功能可以按照以下步骤操作: ### 实现步骤 1. **创建动画对象** - 在GUI设计器中,选中目标控件(如按钮、图片等) - 在属性面板的`动画`选项卡中创建新动画,设置关键帧和过渡效果 - 取消勾选`自动播放`选项(默认可能开启) 2. **添加事件触发器** ```python def event_handler(e): # 获取动画对象(假设动画名称为"my_anim") anim = lv.scr_act().get_child(0).get_child(0).anim # 根据实际层级调整 # 或使用命名获取:lv.anim.get_by_name("my_anim") # 播放动画 anim.play() ``` 3. **绑定事件到控件** ```python # 示例:按钮点击触发 button = lv.btn.create(lv.scr_act()) button.add_event_cb(event_handler, lv.EVENT.CLICKED, None) ``` 4. **高级配置(可选)** - **循环播放**:在动画属性中设置`重复次数`(0表示无限循环) - **反向播放**:使用`anim.reverse()`代替`anim.play()` - **时间轴同步**:多个动画可用`lv.timeline_create()`统一管理 ### 关键注意事项 1. **对象引用** 确保正确获取动画对象引用: - 设计器生成的动画会保存在控件属性中,可通过`控件对象.anim`访问 - 使用`lv.anim.get_by_name()`需先在动画属性中设置唯一名称 2. **动画状态管理** ```python # 停止动画 anim.stop() # 重置到初始状态 anim.set_time(0) ``` 3. **事件类型扩展** 除`lv.EVENT.CLICKED`外,还可绑定: - `lv.EVENT.PRESSED`(按下时触发) - `lv.EVENT.READY`(数据加载完成时) - `lv.EVENT.VALUE_CHANGED`(滑块等控件值变化时) ### 完整示例 ```python def play_animation(e): # 获取已命名动画 anim = lv.anim.get_by_name("icon_anim") anim.play() # 创建按钮 btn = lv.btn.create(lv.scr_act()) btn.center() btn.add_event_cb(play_animation, lv.EVENT.CLICKED, None) # 创建动画目标(图标) icon = lv.img.create(lv.scr_act()) icon.set_src("A:/icon.png") icon.align(lv.ALIGN.CENTER, 0, -100) # 创建动画(设计器中配置的属性会生成类似代码) anim = lv.anim_t() anim.init() anim.set_var(icon) anim.set_values(0, 200) anim.set_time(1000) anim.set_exec_cb(icon, lambda img, val: img.set_y(val)) anim.set_name("icon_anim") ``` > **提示**:实际开发时80%的动画配置可在设计器可视化完成,代码只需处理触发逻辑[^1]。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值