在Qt应用程序中模拟Windows桌面图标的选择行为,即通过上下左右键来移动选择控件,你需要管理一个焦点系统,该系统能够跟踪哪个控件当前被选中,并根据用户的键盘输入来更新这个状态。以下是一个简化的步骤说明和示例代码,展示如何在一个QWidget布局中实现这一功能:
#include <QWidget>
#include <QKeyEvent>
#include <QPushButton>class KeySelecter : public QWidget
{Q_OBJECT
public:explicit KeySelecter(QWidget *parent = nullptr);protected:void keyPressEvent(QKeyEvent *event) override;signals:public slots:private:QList<QPushButton*> buttons;
};#endif // KEYSELECTER_H
KeySelecter::KeySelecter(QWidget *parent) : QWidget(parent)
{QGridLayout *layout = new QGridLayout(this);// 创建按钮并添加到布局中for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {QPushButton *button = new QPushButton(QString("Icon %1").arg((i * 4) + j + 1), this);button->setFocusPolicy(Qt::StrongFocus);layout->addWidget(button, i, j);buttons.append(button);}}// 设置初始焦点if (!buttons.isEmpty()) {buttons.first()->setFocus();}setLayout(layout);
}void KeySelecter::keyPressEvent(QKeyEvent *event)
{static const int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上, 下, 左, 右int currentIndex = buttons.indexOf(qobject_cast<QPushButton*>(focusWidget()));if (currentIndex != -1) {int key = event->key();if (key == Qt::Key_W || key == Qt::Key_S || key == Qt::Key_A || key == Qt::Key_D) {int dirIndex = (key == Qt::Key_W) ? 0 : (key == Qt::Key_S) ? 1 : (key == Qt::Key_A) ? 2 : 3;int newRow = currentIndex / 4 + directions[dirIndex][0];int newCol = currentIndex % 4 + directions[dirIndex][1];// 确保新索引在范围内newRow = qBound(0, newRow, 3);newCol = qBound(0, newCol, 3);int newIndex = newRow * 4 + newCol;if (newIndex >= 0 && newIndex < buttons.size()) {buttons[newIndex]->setFocus();}}}// 如果不是上下左右键,则调用基类方法if (event->key() != Qt::Key_W && event->key() != Qt::Key_S &&event->key() != Qt::Key_A && event->key() != Qt::Key_D) {QWidget::keyPressEvent(event);}
}