QKeyEvent事件的一些解释:
按键:
可重载Widget中的keyPressEvent、keyReleaseEvent、mousePressEvent、mouseReleaseEvent、mouseMoveEvent函数处理
但keyPressEvent有一个问题。在Windows下(别的环境我不知道……),按住一个键时,会先响应一次,停顿一会,然后才开始不断响应。在游戏中这种特性的表现是 人物先走一步,停一下,然后继续不断地走。
这个特性非常影响游戏体验,因此通常的解决方法是:press时,设置某个flag为true,release时,设flag为false,然后在游戏渲染循环中根据flag的值决定人物的行动(即通过忙等待方式而不是中断方式)
但Qt的键盘函数仍然有一个问题,它不是“人按下按键才触发keyPressEvent,弹起按键才触发keyReleaseEvent”,而是“输出按键消息前触发keyPressEvent,输出后触发keyReleaseEvent”。表现为按住一个键时,不断地press、release、press、release、press、release……
好在Qt提供了另一个功能,键盘事件类QKeyEvent中提供autorepeat判断,即按住按键时触发的那些键盘事件属于autorepeat类型,因此可据此排除中间的那些press、release
但Qt的键盘事件依然有一个非常囧的现象(我不清楚为啥会这样),按住一个键时:
1. 触发keyPressEvent,isAutoRepeat()返回false
2. 没有触发keyReleaseEvent,停顿一会
3. 触发keyPressEvent,isAutoRepeat()返回true
4. 触发keyReleaseEvent
5. 若没松开按键,isAutoRepeat()返回true,返回3;松开按键,isAutoRepeat()返回false
所以有时需要设置一个flag避免第二步造成的影响
demo见下面代码:
#include "mainwindow.h"
#include <QKeyEvent>
#include <QDebug>
KeyWidget::KeyWidget(QWidget *parent)
: QWidget(parent)
{
m_keySpace = false;
}
KeyWidget::~KeyWidget()
{
}
void KeyWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Space:
if(!event->isAutoRepeat() && !m_keySpace)
{
m_keySpace = true;
qDebug() << "key press";
}
break;
}
QWidget::keyPressEvent(event);
}
void KeyWidget::keyReleaseEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Space:
if(!event->isAutoRepeat() && m_keySpace)
{
m_keySpace = false;
qDebug() << "key release";
}
break;
}
QWidget::keyReleaseEvent(event);
}