Этот фокус клавиатуры


Я пишу программу на Qt, которая выглядит так:

снимок экрана

Главное окно - это мой класс Window : QWidget, он имеет QGridLayout, содержащий четыре других виджета (Input_Menu : QWidget и Output_Menu : QWidget, а затем два Canvas : QWidget)

Я хотел бы вызвать определенные события, когда пользователь нажимает клавишу. Проблема в том, что Window иногда теряет фокус (он идет, скажем, к Input_Menu, или, возможно, кнопка в Input_Menu...)

Я пробовал следующие решения, но они кажутся неудовлетворительными (и грязный):

  1. дайте Window фокус всякий раз, когда он теряет его.
  2. скажите каждому виджету, у кого может быть фокус, чтобы вызвать функцию Window KeyPressEvent (или ее клон) всякий раз, когда он получает событие клавиатуры.
В идеале, если виджет получает событие (скажем, событие клавиатуры) и не знает, что с ним делать, он должен автоматически вызывать обработчик событий своего родителя. Я бы надеялся, что это будет функцией Qt по умолчанию, но это не похоже на нее. На с другой стороны, я действительно запутался во всем этом фокусе, я действительно не понимаю, что происходит. Может ли кто-нибудь объяснить мне это: я включил std::cout << "key pressed" << std::endl; в свою функцию Window::KeyPressEvent. Когда я впервые запускаю свою программу, кажется, что фокус находится на верхнем QComboBox в Input_Menu: Если я нажимаю клавиши Up/Down, я перемещаюсь в этом окне, и никакая "клавиша нажата" не отображается в моей консоли. Если я попадаю в большинство букв, ничего не происходит. Но если я нажму левую / правую клавиши, я получу "нажатую клавишу" в моей консоли!?

Большое спасибо в продвигайтесь вперед для вашего понимания.

2 2

2 ответа:

Вы можете установить фильтр событий на QApplication, чтобы отфильтровать соответствующие события QEvent::KeyPress глобально. Из документации Qt:

Также можно фильтровать все события для всего приложения, установив фильтр событий на QApplication или QCoreApplication объект. Такие глобальные фильтры событий вызываются перед объектно-ориентированные фильтры. Это очень мощно, но и замедляет процесс. доставка событий каждого отдельного события во всем приложении; другой вместо этого, как правило, следует использовать обсуждаемые методы.

Помимо соображений производительности, не забудьте проверить, имеет ли ваше окно в данный момент фокус, прежде чем фильтровать ключевое событие, или вы можете нарушить всплывающие диалоги или ввод в другие окна.

На самом деле, я обнаружил, что для ключей, которые являются модификаторами (такими как Shift, Control), Qt поддерживает поиск того, нажимаются ли они.

Например: if(QApplication::keyboardModifiers() == Qt::ShiftModifier)...

Этого вполне достаточно.