本章要实现的整体效果如下:
QEvent::KeyPress
键盘按下时,触发该事件,它对应的子类是 QKeyEvent
QEvent::KeyRelease
键盘抬起时,触发该事件,它对应的子类是 QKeyEvent
本节通过两个案例来讲解这 2 个事件:
只需重写 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(ShiftModifier|ControlModifier)
// event->modifiers(),用来判读是否按下 Ctrl/Shift/Alt 键
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);
}
此时,运行程序,可以看到打印如下:
接下来,实现一个小案例:通过上下左右按键,来移动标签的位置
首先,在 key_widget.h
中添加成员变量:
#include
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->setText("");
lbl->setFrameShape(QFrame::Box);
lbl->setFixedSize(100, 100);
lbl->setStyleSheet("background-color: red;");
}
此时,运行效果如下:
只需修改上下左右按键的逻辑即可(当移动到尽头,则从另一端重新出现开始移动):
void KeyWidget::keyPressEvent(QKeyEvent* event)
{
// 普通键
switch ( event->key() ) {
case Qt::Key_Up:
qDebug() << "Up";
lbl->move(lbl->x(), lbl->y() - 20);
if ( lbl->y() + lbl->height() <= 0 ) {
lbl->move(lbl->x(), this->height());
}
break;
case Qt::Key_Down:
qDebug() << "Down";
lbl->move(lbl->x(), lbl->y() + 20);
if ( lbl->y() >= this->height() ) {
lbl->move(lbl->x(), 0);
}
break;
case Qt::Key_Left:
qDebug() << "Left";
lbl->move(lbl->x() - 20, lbl->y());
if ( lbl->x() + lbl->width() <= 0 ) {
lbl->move(this->width(), lbl->y());
}
break;
case Qt::Key_Right:
qDebug() << "Right";
lbl->move(lbl->x() + 20, lbl->y());
if ( lbl->x() >= this->width() ) {
lbl->move(0, lbl->y());
}
break;
}
}
此时,按键盘上的上下左右箭头,效果如下: