前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt键盘事件(二)——长按按键反复触发event事件问题解决

Qt键盘事件(二)——长按按键反复触发event事件问题解决

作者头像
用户6557940
发布2022-07-24 15:25:25
3.4K0
发布2022-07-24 15:25:25
举报
文章被收录于专栏:Jungle笔记

引言

Qt键盘事件可能会遇到无法响应方向键、一直产生按下或者释放事件等问题,如何解决呢?Jungle笔记为您解答。

01

问题描述

在Jungle的上一篇文章中(Qt键盘事件(一)——检测按键输入),Jungle简单实现了利用qt检测用户按键操作并将键按下\释放操作打印在Qt界面上的一个小程序。但是在测试过程中会出现一个现象,那就是长按某个键不放,界面一直在刷新press、release、press、release……(如下图)

也就是说,在长按某个键不释放的情况下,keyPressEvent和keyReleaseEvent事件会不断被触发。尽管这是Qt设计实现好的事件机制,但在用户体验上,这是不合常理的。我们希望实现的是:按下某个键(比如Tab键),界面只打印一次"Key_Tab Press";当手松开时,界面上才打印"Key_Tab Release"

02

问题说明

为此,Jungle查询了Qt官方文档和几篇博客。官方文档上提到一个QKeyEvent的成员函数isAutoRepeat:

可以看到,当event来自于auto-repeating key,isAutoRepeat返回true;当event事件来自于最初的按键,则sAutoRepeat返回false。这么说可能不好理解,那不妨Jungle做个小测试:

在keyPressEvent里打印isAutoRepeat返回值

操作:长按Tab键,在keyPressEvent里打印isAutoRepeat返回值,松开Tab键后,再次长按Tab键,再松开。

代码语言:javascript
复制
void QKeyBoard::keyPressEvent(QKeyEvent *event){
  switch(event->key()){
    case Qt::Key_Tab:
      if(event->isAutoRepeat()==true){
        this->ui.textEdit_press->append("true");
      }
      else{
        this->ui.textEdit_press->append("false");
      }
      this->ui.textEdit_press->append("Key_Tab Press");
      break;
    /*default:
      this->ui.textEdit->append("KeyEvent");*/
  }
}

测试结果如下图:

从测试结果可以看到,长按下Tab键第一次触发keyPressEvent事件时isAutoRepeat返回false,之后长按过程中isAutoRepeat返回值均为true。松键后再次长按,isAutoRepeat返回false,之后长按过程中isAutoRepeat返回值均为true。即只有首次按下Tab键时,isAutoRepeat返回值为false。结合这个结果来看Qt官方文档的描述,似乎更好理解一点。

在keyReleaseEvent里打印isAutoRepeat返回值

同样,Jungle在keyReleaseEvent里打印isAutoRepeat返回值,运行结果如上图(代码略)。可以看到,长按下Tab键,自动触发keyReleaseEvent事件时isAutoRepeat返回true,真正松键后触发keyReleaseEvent事件时isAutoRepeat返回true

测试总结

结合Qt官方文档和上述测试,可以得出如下结论:

  • 按键触发的keyPressEvent事件,isAutoRepeat返回false;自动触发的keyPressEvent事件,isAutoRepeat返回true;
  • 松键触发的keyReleaseEvent事件,isAutoRepeat返回true;自动触发的keyReleaseEvent事件,isAutoRepeat返回false。

03

问题解决

在真正按键和松键事件触发时,加上对isAutoRepeat返回值的判断,具体判断如第2节总结所言,示例代码如下:

代码语言:javascript
复制
void QKeyBoard::keyPressEvent(QKeyEvent *event){
  switch(event->key()){
    case Qt::Key_Tab:
      if(!event->isAutoRepeat()){
        this->ui.textEdit_press->append("Key_Tab Press");
                /* add your code here*/
      }
      break;
  
    /*default:
      this->ui.textEdit->append("KeyEvent");*/
  }
}
 
void QKeyBoard::keyReleaseEvent(QKeyEvent *event){
  switch(event->key()){
    case Qt::Key_Tab:
      if(!event->isAutoRepeat()){
        this->ui.textEdit_release->append("Key_Tab Release");
                /* add your code here*/
      }
      break;
    /*default:
      this->ui.textEdit->append("KeyEvent");*/
  }
}

在某些博客里,作者可能增设了某个变量来标记键是否被按下,并在按下和松键时更新标记。但Jungle认为并没有必要,像上述那样加入判断即可。相关代码请访问Jungle的GitHub主页:https://github.com/FengJungle/Qt_Project

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Jungle笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在keyReleaseEvent里打印isAutoRepeat返回值
  • 测试总结
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档