[SOLVED] How to set focus for button in KeyPressEvent for key_up, key_down. QT

Issue

I have a Form with buttons called "Up", "Down", etc.

I need to process keyboard buttons (arrow_up, arrow_down, etc). Parallelly I want to set focus for relevant buttons.

For Example: If I pressed the arrow_down button on keyboard then the "Down" button would be a focus on my Form.

My variant how to do this:

bool ClientWindow::eventFilter(QObject *obj, QEvent *e)
{
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *event= dynamic_cast<QKeyEvent*>(e);
        switch(event->key()) {
            case Qt::Key_Up: ui->up->setFocus(); ;break;
            case Qt::Key_Down: ui->down->setFocus(); break;
            case Qt::Key_Left: ui->left->setFocus(); break;
            case Qt::Key_Right: ui->right->setFocus(); break;
        }
    }
    return QObject::eventFilter(obj, event);
}

But, focus isn’t set, and

1) If I return true from eventFilter then focus wouldn’t set.

2) If I return QObject::eventFilter(obj, event) then focus would be transferred to next Object.

How to set focus for the relevant button?

Solution

Since you’re trying to change a standard feature of Qt (arrow keys move focus just like TAB key does), you may want to try an extreme solution.

The point is: are your arrow key press events even being filtered at all? My guess is no. Something above (or before) the widget is consuming them and keeps the standard behavior unchanged (focus move from button to button according to their tab-indexes as usual).

I would try installing your filter onto the QApplication object, in the widget constructor this way:

qApp->installEventFilter(this);

The filter should look like this:

bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    if (e->type() == QEvent::KeyPress)
    {
        if(qApp->activeWindow() == this)
        {
            QKeyEvent *event= dynamic_cast<QKeyEvent*>(e);

            switch(event->key()) {
            case Qt::Key_Up: ui->up->setFocus(); break;
            case Qt::Key_Down: ui->down->setFocus(); break;
            case Qt::Key_Left: ui->left->setFocus(); break;
            case Qt::Key_Right: ui->right->setFocus(); break;

            default:
                return qApp->eventFilter(obj, e);

            }
            return true;
        }
    }
    return qApp->eventFilter(obj, e);
}

Please notice this line:

if(qApp->activeWindow() == this)

which should prevent the rule in the filter to be applied whenever the arrow keys get pressed (i.e. when the widget isn’t the topmost one). You can ignore that, if your application hasn’t other widget than this one.

Final advice: try to never change the standard UI behavior. Users do expect things to work as usual, and solutions that look absolutely cool to the developer, sometimes (often), brings no improvements at all and only confuse the user.

Answered By – p-a-o-l-o

Answer Checked By – Dawn Plyler (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *