0

8 つのボタン (2x4) のグリッドを作成し、キーボードの矢印を使用してこのボタンを移動できるようにしたいと考えています。単純にグリッド レイアウトを作成し、プッシュボタンを対応する座標に配置すると、本来のレイアウトが得られますが、左右にしか移動できず、最初の行の最後に来ると、フォーカスが最初のボタンにジャンプします2 行目 (つまり、UP ボタンはフォーカスを下に移動せず、代わりにボタン RIGHT と同じように移動します)。フォーカス (カーソル) がボタン間を移動する方法がグリッド内の場所に接続されていないことに気付きましたが、コードでそれらを作成しました。

この動作を無効にして、ユーザーがボタンのグリッドを移動できるようにする方法は?

4

1 に答える 1

0

すべてのボタンにイベント フィルターをインストールし、そこでキーの押下をキャッチできます。

これは、そのようなナビゲーションを実装する方法の例です:

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    grid = new QGridLayout;

    for (int row = 0; row < 4; ++row)
    {
        for (int col = 0; col < 4; ++col)
        {
            QString text = QString("btn %1/%2").arg(row).arg(col);
            QPushButton *btn = new QPushButton(text);
            btn->installEventFilter(this);

            grid->addWidget(btn, row, col);
        }
    }

    setLayout(grid);
}

bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    QPushButton *btn = dynamic_cast<QPushButton*>(obj);
    if (btn != NULL && event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);

        int index = grid->indexOf(btn);
        int row, col, rowSpan, colSpan;
        grid->getItemPosition(index, &row, &col, &rowSpan, &colSpan);

        int nextRow = row;
        int nextCol = col;

        bool keyArrow = true;
        int key = keyEvent->key();
        switch (key)
        {
        case Qt::Key_Up:
        {
            nextRow--;
            if (nextRow < 0)
            {
                nextRow = grid->rowCount() - 1;
            }
            break;
        }
        case Qt::Key_Down:
        {
            nextRow++;
            if (nextRow >= grid->rowCount())
            {
                nextRow = 0;
            }
            break;
        }
        case Qt::Key_Right:
        {
            nextCol++;
            if (nextCol >= grid->columnCount())
            {
                nextCol = 0;
            }
            break;
        }
        case Qt::Key_Left:
        {
            nextCol--;
            if (nextCol < 0)
            {
                nextCol = grid->columnCount() - 1;
            }
            break;
        }
        default:
        {
            keyArrow = false;
        }
        }

        if (keyArrow)
        {
            grid->itemAtPosition(nextRow, nextCol)->widget()->setFocus();
        }

        return true;

    }

    return QWidget::eventFilter(obj, event);
}
于 2013-10-03T08:19:59.220 に答える