本节讲解两个事件:
- 键盘按下事件(QEvent::KeyPress)
- 键盘释放事件(QEvent::KeyRelease)
当键盘按下和释放时,会被触发。该事件对应的子类是QKeyEvent
本节通过两个案例来讲解这 2 个事件:
- 键盘按下、释放事件的基本使用
- 通过键盘的上下左右键,控制标签控件的移动
本节实现的效果,如下:
1. 基本使用
只需重写keyPressEvent()和keyPressEvent()两个函数即可
首先,在 key_widget.h 中添加两个函数的声明
class KeyWidget : public QWidget {
protected:
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
};
然后,来到key_widget.cpp实现这2个函数:
void KeyWidget::keyPressEvent(QKeyEvent* event)
{ // 单键
switch (event->key()) {
case Qt::Key_Return: qDebug() << "Enter"; break;
case Qt::Key_Escape: qDebug() << "Esc"; break;
case Qt::Key_Control: qDebug() << "Ctrl"; break;
case Qt::Key_Shift: qDebug() << "Shift"; break;
case Qt::Key_Alt: qDebug() << "Alt"; break;
case Qt::Key_Up: qDebug() << "Up"; break;
case Qt::Key_Down: qDebug() << "Down"; break;
case Qt::Key_Left: qDebug() << "Left"; break;
case Qt::Key_Right: qDebug() << "Right"; break;
case Qt::Key_A: qDebug() << "A"; break;
case Qt::Key_B: qDebug() << "B"; break;
case Qt::Key_C: qDebug() << "C"; break;
case Qt::Key_D: qDebug() << "D"; break;
default: break;
}
// 两键组合
// qDebug() << event->modifiers(); // QFlags<Qt::KeyboardModifier>(ShiftModifier|ControlModifier)
if ((event->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_A)) {
qDebug() << "Ctrl + A";
}
if ((event->modifiers() == Qt::ShiftModifier) && (event->key() == Qt::Key_C)) {
qDebug() << "Shift + B";
}
if ((event->modifiers() == Qt::AltModifier) && (event->key() == Qt::Key_B)) {
qDebug() << "ALT + C";
}
// 三键组合Shift + Ctrl + D 的实现
if ((event->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) && (event->key() == Qt::Key_D)) {
qDebug() << "CTRL + Shift + D";
}
}
void KeyWidget::keyReleaseEvent(QKeyEvent* event)
{
switch (event->key()) {
case Qt::Key_Return: qDebug() << "keyReleaseEvent: Enter"; break;
case Qt::Key_Escape: qDebug() << "keyReleaseEvent: Esc"; break;
case Qt::Key_Up: qDebug() << "keyReleaseEvent: Up"; break;
case Qt::Key_Down: qDebug() << "keyReleaseEvent: Down"; break;
case Qt::Key_Left: qDebug() << "keyReleaseEvent: Left"; break;
case Qt::Key_Right: qDebug() << "keyReleaseEvent: Right"; break;
case Qt::Key_A: qDebug() << "keyReleaseEvent: A"; break;
case Qt::Key_B: qDebug() << "keyReleaseEvent: B"; break;
case Qt::Key_C: qDebug() << "keyReleaseEvent: C"; break;
case Qt::Key_D: qDebug() << "keyReleaseEvent: D"; break;
case Qt::Key_Control: qDebug() << "keyReleaseEvent: Ctrl"; break;
case Qt::Key_Shift: qDebug() << "keyReleaseEvent: Shift"; break;
case Qt::Key_Alt: qDebug() << "keyReleaseEvent: Alt"; break;
}
}
说明:
- 每个按键对应一个枚举值,比如
Qt::Key_A代表按键A,Qt::Key_Control代表Crtl键,等等 QKeyEvent类的key()方法,可以获取当前按下的哪个按键- 判断
Ctrl/Shift/Alt等控制按键,需要使用QKeyEvent类的modifiers()方法
最后,还需要在构造中添加如下语句:
KeyWidget::KeyWidget(QWidget* parent) : QWidget{parent}
{
setFocusPolicy(Qt::StrongFocus);
}
此时,运行程序,可以看到打印如下:
2. 案例:键盘移动标签
接下来,实现一个小案例:通过上下左右按键,来移动标签的位置
2.1 界面上添加标签
首先,在key_widget.h中添加成员变量:
#include <QLabel>
class KeyWidget : public QWidget {
private:
QLabel *lbl;
};
然后,在key_widget.cpp的构造中添加一个标签:
KeyWidget::KeyWidget(QWidget* parent) : QWidget{parent}
{
setFocusPolicy(Qt::StrongFocus);
// 添加一个 QLabel
lbl = new QLabel(this);
lbl->setFrameShape(QFrame::Box);
lbl->setFixedSize(100, 100);
lbl->setStyleSheet("background-color: red;");
}
此时,运行效果:
2.2 移动标签
只需修改上下左右按键的逻辑即可(当移动到尽头,则从另一端重新出现开始移动):
void KeyWidget::keyPressEvent(QKeyEvent* event)
{
QPoint p = lbl->pos();
int width = lbl->width();
int height = lbl->height();
switch (event->key()) {
case Qt::Key_Up:
p.setY(p.y() - 20);
if (p.y() + height <= 0) {
p.setY(this->height());
}
break;
case Qt::Key_Down:
p.setY(p.y() + 20);
if (p.y() > this->height()) {
p.setY(-height);
}
break;
case Qt::Key_Left:
p.setX(p.x() - 20);
if (p.x() + width <= 0) {
p.setX(this->width());
}
break;
case Qt::Key_Right:
p.setX(p.x() + 20);
if (p.x() > this->width()) {
p.setX(-width);
}
break;
}
lbl->move(p);
}
此时,按键盘上的上下左右箭头,效果如下:






