Как мне отключить поведение Qt в Linux для захвата клавиш со стрелками для навигации по фокусу виджета

#linux #qt #events #keyboard

#linux #qt #Мероприятия #клавиатура

Вопрос:

Я работаю над приложением Qt, которое разрабатывается в основном для macOS, но затем создается и тестируется также в Linux.

Мы определяем метод keyPressEvent () в нашем классе главного окна для реагирования на определенные события клавиатуры. Среди прочего, мы реагируем на Qt:: Key_Left, Qt:: Key_Right и Qt::Key_Space. Это отлично работает на macOS. Однако в Linux мы никогда не получаем эти события.

Немного погуглив (и подтвердив это поведением нашего приложения в Linux), кажется, что причина этого в том, что Qt использует эти клавиши для навигации с клавиатуры по виджетам кнопок в графическом интерфейсе приложения. Если я нажимаю клавиши со стрелками в Linux, я перебираю все активные виджеты кнопок, выбирая каждый по очереди. Если я нажму пробел, будет нажата выбранная в данный момент кнопка.

Все, что я смог найти до сих пор, поискав в Google, — это предложения о том, как либо подклассировать, либо применить фильтры к определенным кнопкам, чтобы избежать такого поведения, заставив кнопку игнорировать событие и передавать его дальше. Но я не хочу делать это для каждого виджета кнопки, который я когда-либо вставлял в свой графический интерфейс. Это просто неубедительно.

Есть ли способ отключить это поведение глобально и позволить моему коду приложения фактически получать ВСЕ события со стрелками и пробелом?

Комментарии:

1. Можете ли вы подтвердить, что это также относится к Qt: Key_PageUp Qt::Key_PageDown?

Ответ №1:

Вы можете настроить добавить глобальный прослушиватель событий, чтобы перехватывать эти события.

В конструкторе window:

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

В методе eventFilter окна:

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

Если вы обработали событие, вы должны вернуться true из этой функции. Вы можете использовать object переменную, чтобы узнать источник события. Например, это может быть какая-нибудь QPushButton. Вы можете проверить, является ли эта кнопка дочерней для вашего главного окна, если это необходимо (если у вас несколько верхних окон).

Другой способ — полностью отключить фокусировку для кнопок. Установите для кнопок focusPolicy значение NoFocus . Тогда они не будут перехватывать ключевые события.

Также вы можете создать подкласс QPushButton и переопределить keyPressEvent с пустой реализацией.