0


Qt响应多个按键同时按下

1.Qt的键盘事件:

voidkeyReleaseEvent(QKeyEvent *);//按键释放事件voidkeyPressEvent(QKeyEvent *);//按键按下事件

2.Qt可以响应的按键事件:

单个按键、组合键(例如:crtl+c)
注意:

  1. 当单个按键按下释放后,按键事件还会停顿一下,所以我们不能在按键事件里面直接处理逻辑。--------借助定时器。
  2. 如果我们想响应多个按键同时按下的效果,单凭这键盘事件是没办法实现的。-------借助容器

3.借助定时器和容器,实现多个按键按下的同时响应

  1. 以WASD四按键为例,实现QLabel控件的丝滑移动。首先准备一个容器用于存放按下按键的keyQList<int> keys;//头文件中添加成员
  2. 定义一个定时器用于遍历容器QTimer* keyRespondTimer;//头文件中添加成员keyRespondTimer =newQTimer(this);//构造函数中创建定时器对象,并连接信号槽connect(keyRespondTimer,&QTimer::timeout,this,&Widget::slotTimeOut);
  3. 处理按键按下事件voidWidget::keyPressEvent(QKeyEvent *event){if(!event->isAutoRepeat())//判断如果不是长按时自动触发的按下,就将key值加入容器 keys.append(event->key());if(!keyRespondTimer->isActive())//如果定时器不在运行,就启动一下 keyRespondTimer->start(4);}
  4. 处理按键释放事件voidWidget::keyReleaseEvent(QKeyEvent *event){if(!event->isAutoRepeat())//判断如果不是长按时自动触发的释放,就将key值从容器中删除 keys.removeAll(event->key());if(keys.isEmpty())//容器空了,关闭定时器 keyRespondTimer->stop();}

注意点

if(!event->isAutoRepeat())

,增加这一判断是为了避免在按键长按期间一直触发按键事件,对同一键值一直做容器追加和删除操作。这显然是没必要的耗时操作,我们只需要保证在长按期间,那个按键的键值key一直在容器里就好了。

  1. 遍历key值容器,实现多个按键的同时响应voidWidget::slotTimeOut(){foreach(int key, keys){switch(key){case Qt::Key_W: ui->label->move(ui->label->x(), ui->label->y()-1);break;case Qt::Key_A: ui->label->move(ui->label->x()-1, ui->label->y());break;case Qt::Key_S: ui->label->move(ui->label->x(), ui->label->y()+1);break;case Qt::Key_D: ui->label->move(ui->label->x()+1, ui->label->y());break;default:break;}}}

4.效果图

在这里插入图片描述

5.源码

#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<QTimer>#include<QKeyEvent>

QT_BEGIN_NAMESPACE
namespace Ui {classWidget;}
QT_END_NAMESPACE

classWidget:publicQWidget{
    Q_OBJECT

public:Widget(QWidget *parent =nullptr);~Widget();protected:voidkeyPressEvent(QKeyEvent *event)override;voidkeyReleaseEvent(QKeyEvent *event)override;private:
    Ui::Widget *ui;
    QList<int> keys;
    QTimer* keyRespondTimer;voidslotTimeOut();};#endif// WIDGET_H
#include"widget.h"#include"ui_widget.h"Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
    ui->setupUi(this);
    keyRespondTimer =newQTimer(this);connect(keyRespondTimer,&QTimer::timeout,this,&Widget::slotTimeOut);}Widget::~Widget(){delete keyRespondTimer;delete ui;}voidWidget::keyPressEvent(QKeyEvent *event){if(!event->isAutoRepeat())//判断如果不是长按时自动触发的按下,就将key值加入容器
        keys.append(event->key());if(!keyRespondTimer->isActive())//如果定时器不在运行,就启动一下
        keyRespondTimer->start(4);}voidWidget::keyReleaseEvent(QKeyEvent *event){if(!event->isAutoRepeat())//判断如果不是长按时自动触发的释放,就将key值从容器中删除
        keys.removeAll(event->key());if(keys.isEmpty())//容器空了,关闭定时器
        keyRespondTimer->stop();}voidWidget::slotTimeOut(){foreach(int key, keys){switch(key){case Qt::Key_W:
            ui->label->move(ui->label->x(), ui->label->y()-1);break;case Qt::Key_A:
            ui->label->move(ui->label->x()-1, ui->label->y());break;case Qt::Key_S:
            ui->label->move(ui->label->x(), ui->label->y()+1);break;case Qt::Key_D:
            ui->label->move(ui->label->x()+1, ui->label->y());break;default:break;}}}
标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/Jerich2213/article/details/127816451
版权归原作者 Jerich morningStar 所有, 如有侵权,请联系我们删除。

“Qt响应多个按键同时按下”的评论:

还没有评论