在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);}
}