目录
一、前言
Qt框架支持通过键盘输入来间接控制界面元素,如按钮,实现无需鼠标操作的交互方式。这通常涉及到键盘事件的监听与处理,比如监听特定的按键事件(如空格键、回车键等),并在这些事件发生时模拟鼠标点击行为,触发按钮的点击事件。本文通过重写键盘事件处理函数keyPressEvent来实现这一功能,从而为应用程序添加更丰富的交互体验和便捷性。
二、初始化
创建多个按钮并添加到网格布局中,并将按钮的点击信号与槽函数相连接,以方便后续验证键盘控制效果。
// 创建网格布局
QGridLayout *grid = new QGridLayout(this);
// 创建按钮
QPushButton *button1 = new QPushButton("按钮1");
QPushButton *button2 = new QPushButton("按钮2");
QPushButton *button3 = new QPushButton("按钮3");
QPushButton *button4 = new QPushButton("按钮4");
//链接按钮点击信号与槽函数
connect(button1, &QPushButton::clicked, this, &Widget::Button_clicked);
connect(button2, &QPushButton::clicked, this, &Widget::Button_clicked);
connect(button3, &QPushButton::clicked, this, &Widget::Button_clicked);
connect(button4, &QPushButton::clicked, this, &Widget::Button_clicked);
// 将按钮添加到网格布局
grid->addWidget(button1, 0, 0); // 将button1添加到第0行第0列
grid->addWidget(button2, 0, 1); // 将button2添加到第0行第1列
grid->addWidget(button3, 1, 0); // 将button3添加到第1行第0列
grid->addWidget(button4, 1, 1); // 将button3添加到第1行第1列
设置按钮的objectname,并将按钮保存到QList中去,方便后续键盘控制按钮时知道需要控制哪个按钮。
//设置button的objectname
button1->setObjectName(QString("button-0-0"));
button2->setObjectName(QString("button-0-1"));
button3->setObjectName(QString("button-1-0"));
button4->setObjectName(QString("button-1-1"));
//将按钮添加到QList中去
buttons << button1 << button2 << button3 << button4;
初始化的整体代码:
//键盘控制按钮的选中
void Widget::keyboardChoose()
{
// 创建网格布局
QGridLayout *grid = new QGridLayout(this);
// 创建按钮
QPushButton *button1 = new QPushButton("按钮1");
QPushButton *button2 = new QPushButton("按钮2");
QPushButton *button3 = new QPushButton("按钮3");
QPushButton *button4 = new QPushButton("按钮4");
//链接按钮点击信号与槽函数
connect(button1, &QPushButton::clicked, this, &Widget::Button_clicked);
connect(button2, &QPushButton::clicked, this, &Widget::Button_clicked);
connect(button3, &QPushButton::clicked, this, &Widget::Button_clicked);
connect(button4, &QPushButton::clicked, this, &Widget::Button_clicked);
//设置button的objectname
button1->setObjectName(QString("button-0-0"));
button2->setObjectName(QString("button-0-1"));
button3->setObjectName(QString("button-1-0"));
button4->setObjectName(QString("button-1-1"));
//将按钮添加到QList中去
buttons << button1 << button2 << button3 << button4;
// 将按钮添加到网格布局
grid->addWidget(button1, 0, 0); // 将button1添加到第0行第0列
grid->addWidget(button2, 0, 1); // 将button2添加到第0行第1列
grid->addWidget(button3, 1, 0); // 将button3添加到第1行第0列
grid->addWidget(button4, 1, 1); // 将button3添加到第1行第1列
//设置按钮边界
down = 1;
right = 1;
// 初始选中第一个按钮
currentButton = buttons[0];
currentButton->setStyleSheet("QPushButton:focus { background-color: yellow; }");
}
三、键盘移动后需要选中哪个按钮
通过遍历之前保存button的QList,比较每个button的objectname属性,找到需要选中的那个按钮
QPushButton* Widget::judgeMove(QString newButtonName)
{
QPushButton *button = nullptr;
for(auto it : buttons)
{
if(it->objectName() == newButtonName)
{
button = it;
}
}
return button;
}
四、键盘按键处理函数
本文将W键设置为上,S键设置为下,A键设置为左,D键设置为右,Enter键设置为点击按钮
//键盘按键处理函数
void Widget::keyPressEvent(QKeyEvent *event)
{
QStringList list = currentButton->objectName().split("-");
switch (event->key()) {
case Qt::Key_W:
//up
if (list.at(1).toInt() > 0) {
currentButton->setStyleSheet("");
QString newButtonName = QString("button-%1-%2").arg(list.at(1).toInt() - 1).arg(list.at(2));
currentButton = judgeMove(newButtonName);
if(currentButton)
{
currentButton->setStyleSheet("QPushButton:focus { background-color: yellow; }");
currentButton->setFocus();
}
}
break;
case Qt::Key_S:
//down
if (list.at(1).toInt() < down) {
currentButton->setStyleSheet("");
QString newButtonName = QString("button-%1-%2").arg(list.at(1).toInt() + 1).arg(list.at(2));
currentButton = judgeMove(newButtonName);
if(currentButton)
{
currentButton->setStyleSheet("QPushButton:focus { background-color: yellow; }");
currentButton->setFocus();
}
}
break;
case Qt::Key_A:
//left
if (list.at(2).toInt() > 0) {
currentButton->setStyleSheet("");
QString newButtonName = QString("button-%1-%2").arg(list.at(1)).arg(list.at(2).toInt() - 1);
currentButton = judgeMove(newButtonName);
if(currentButton)
{
currentButton->setStyleSheet("QPushButton:focus { background-color: yellow; }");
currentButton->setFocus();
}
}
break;
case Qt::Key_D:
//right
if (list.at(2).toInt() < right) {
currentButton->setStyleSheet("");
QString newButtonName = QString("button-%1-%2").arg(list.at(1)).arg(list.at(2).toInt() + 1);
currentButton = judgeMove(newButtonName);
if(currentButton)
{
currentButton->setStyleSheet("QPushButton:focus { background-color: yellow; }");
currentButton->setFocus();
}
}
break;
case 16777220:
//Enter
currentButton->click();
break;
default:
QWidget::keyPressEvent(event);
}
}