Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I disable Qt's behavior on Linux of capturing arrow keys for widget focus navigation

I'm working on a Qt app that is developed primarily on MacOS, but that is then built and tested on Linux as well.

We define a keyPressEvent() method in our main window class to respond to certain keyboard events. Among others, we respond to Qt::Key_Left, Qt::Key_Right and Qt::Key_Space. This works great on MacOS. On Linux, however, we never get these events.

Doing some Googling (and confirming it with our app's behavior on Linux), it seems that the reason for this is that Qt uses these keys for keyboard navigation of button widgets in the application's GUI. If I press the arrow keys on Linux, I cycle through all the active button widgets, selecting each on in turn. If I click the spacebar, the currently selected button is pressed.

All I've been able to find so far by Googling is suggestions as to how to either subclass or apply filters to specific buttons to avoid this behavior by having the button ignore the event and pass it along. But I don'w want to have to do this for every button widget I ever put into my GUI. That's just lame.

Is there a way to disable this behavior globally and allow my app code to actually get ALL of the arrow key and spacebar events?

like image 852
Steve Avatar asked Nov 05 '22 22:11

Steve


1 Answers

You can set add global event listener to catch these events.

In the window constructor:

QApplication::instance()->installEventFilter(this);

In the window's eventFilter method:

bool MainWindow::eventFilter(QObject *object, QEvent *event) {
  if (event->type() == QEvent::KeyPress) {
    QKeyEvent* key_event = static_cast<QKeyEvent*>(event);
    qDebug() << "key" << key_event->key() << "object" << object;
    //...
  }
  return false;
}

If you have processed an event, you should return true from this function. You can use object variable to find out the source of event. For example, it can be some QPushButton. You can check if this button is a child of your main window if it's necessary (if you have multiple top windows).

Another way is to disable focus for buttons completely. Set buttons' focusPolicy to NoFocus. Then they will not catch key events.

Also you can subclass QPushButton and reimplement keyPressEvent with empty implementation.

like image 108
Pavel Strakhov Avatar answered Nov 09 '22 10:11

Pavel Strakhov