扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

TouchGFX 按钮长按实现指南:ClickListener+Tick 事件高效方案

01/27 17:49
660
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在 TouchGFX UI 设计中,让同一按钮通过短按 / 长按实现不同功能是高频需求。普通 Button 控件仅支持基础点击交互,需通过自定义配置实现长按识别。本文基于 ST 官方 LAT1300 应用笔记,详解 “ClickListener+handleTickEvent” 的实现方法,步骤简洁、可直接复用,适用于 TouchGFX 4.21.3 及以上版本。

1. 核心原理:长按识别的底层逻辑

实现长按的核心是 “触控状态监测 + 计时统计”,依赖 TouchGFX 的两个核心机制:
  1. ClickListenerMixin:为 Button 控件添加点击事件响应能力,可捕获PRESSED(按下)和RELEASED(释放)两种状态;
  2. handleTickEvent 函数:TouchGFX 引擎以 60Hz 频率自动调用(约 16.7ms / 次),用于实现精准计时,判断按键按下时长是否达到长按阈值。

2. 实操步骤:从配置到功能实现

以 “长按 3 秒切换文本显示” 为例,完整实现流程分 4 步,适配所有 TouchGFX 支持的 STM32 芯片

2.1 第一步:创建按钮并启用 ClickListener

在 TouchGFX Designer 中完成基础配置,让按钮具备触控响应能力:
  1. 拖拽 Button 控件到 UI 界面,命名为button1
  2. 勾选 Mixins 面板中的ClickListener选项,启用触控事件响应;
    • 启用后,控件声明自动变为touchgfx::ClickListener<touchgfx::Button> button1;,支持捕获点击事件。

2.2 第二步:绑定回调函数,响应触控状态

在按钮所属 Screen 的代码中,声明并绑定回调函数,处理PRESSEDRELEASED事件:

(1)头文件(Screen1View.hpp)声明

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    virtual void handleTickEvent(); // 后续计时用,提前声明

protected:
    // 回调函数声明:参数为按钮对象和点击事件
    void ButtonClickHandler(const Button& b, const ClickEvent& e);
    // 回调绑定对象:关联当前视图和处理函数
    Callback<Screen1View, const Button&, const ClickEvent&> buttonClickedCallback;
    
    // 新增变量:长按计时计数器、长按阈值(3秒=60Hz×3=180次)
    uint32_t pressCounter = 0;
    const uint32_t LONG_PRESS_THRESHOLD = 180;
    bool isPressing = false; // 按压状态标记
};

(2)源文件(Screen1View.cpp)绑定与实现

// 构造函数:绑定回调对象与处理函数
Screen1View::Screen1View() : 
    buttonClickedCallback(this, &Screen1View::ButtonClickHandler) {}

// 初始化屏幕时,为按钮设置点击动作
void Screen1View::setupScreen() 
{
    Screen1ViewBase::setupScreen();
    button1.setClickAction(buttonClickedCallback); // 绑定回调
}

// 回调处理函数:捕获按压/释放状态
void Screen1View::ButtonClickHandler(const Button& b, const ClickEvent& e) 
{
    if (&b == &button1) // 确认是目标按钮
    {
        if (e.getType() == ClickEvent::PRESSED) 
        {
            // 按下时初始化:重置计数器、标记按压状态
            pressCounter = 0;
            isPressing = true;
        }
        else if (e.getType() == ClickEvent::RELEASED) 
        {
            // 释放时重置状态
            isPressing = false;
            // 此处可添加短按功能(如需要)
            // 示例:if (pressCounter < LONG_PRESS_THRESHOLD) { 短按逻辑 }
        }
    }
}

2.3 第三步:实现 handleTickEvent,完成计时与长按判断

handleTickEvent以 60Hz 频率调用,用于统计按压时长,达到阈值则触发长按功能:
void Screen1View::handleTickEvent()
{
    if (isPressing) // 仅在按压状态下计时
    {
        pressCounter++; // 每次调用计数+1(约16.7ms)
        // 达到3秒阈值(180次计数),且未触发过长按(避免重复执行)
        if (pressCounter >= LONG_PRESS_THRESHOLD)
        {
            // 长按功能实现:示例为切换文本显示
            text1.setTypedText(TypedText(T_TEXT_LONG_PRESS));
            text1.invalidate(); // 刷新文本控件
            
            // 重置状态,避免持续触发
            isPressing = false;
            pressCounter = 0;
        }
    }
}

2.4 第四步:效果验证

编译工程并下载到开发板,测试效果符合预期:
  • 短按按钮(少于 3 秒):仅触发RELEASED事件,文本无变化;
  • 长按按钮(超过 3 秒):触发长按逻辑,文本从 “Please press the button” 切换为 “You have pressed more than 3s”。

3. 核心扩展:灵活适配不同需求

3.1 调整长按时长

修改LONG_PRESS_THRESHOLD值即可,计算公式:阈值 = 目标时长(秒)× 60,示例:
  • 2 秒长按:const uint32_t LONG_PRESS_THRESHOLD = 120;
  • 5 秒长按:const uint32_t LONG_PRESS_THRESHOLD = 300;

3.2 同时支持短按 + 长按

RELEASED事件中添加短按判断,示例:
else if (e.getType() == ClickEvent::RELEASED) 
{
    if (pressCounter < LONG_PRESS_THRESHOLD && pressCounter > 0)
    {
        // 短按逻辑:示例为恢复初始文本
        text1.setTypedText(TypedText(T_TEXT_SHORT_PRESS));
        text1.invalidate();
    }
    isPressing = false;
    pressCounter = 0;
}

3.3 适配其他 Widget

除 Button 外,TextArea、Image 等控件均可通过勾选ClickListener,复用本文逻辑实现长按功能,仅需修改回调函数中的控件判断条件。

4. 注意事项与避坑指南

  1. 计时精度handleTickEvent调用频率为 60Hz,计时误差极小,满足绝大多数场景需求;
  2. 状态重置:必须在长按触发后、按压释放时重置isPressingpressCounter,避免重复触发;
  3. 控件刷新:修改文本、图片等 UI 元素后,需调用invalidate()函数刷新显示;
  4. 版本兼容性:TouchGFX 4.21.3 及以上版本均支持该方案,低版本需升级后使用。

5. 核心优势总结

  • 轻量高效:无需额外定时器,依赖 TouchGFX 原生机制,CPU 占用低;
  • 配置简单:仅需 4 步,代码量少,可直接复制复用;
  • 灵活可控:长按时长、功能逻辑可按需自定义,适配多样化 UI 需求。
该方案是 TouchGFX 中实现按钮长按的标准方法,适用于智能家居控制面板、工业设备 UI、消费电子触控界面等各类场景。

相关推荐