QKeyEvent isAutoRepeat не работает?

Итак, у меня есть приложение, в котором, если удерживать нажатой определенную кнопку, оно воспроизводит аудиоустройство, а при отпускании кнопки останавливает аудиоустройство. я использую keyPressEvent а также KeyReleaseEvent реализовать это, что похоже на код ниже:

void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(event->isAutoRepeat())
{
event->ignore();
}
else
{
if(event->key() == Qt::Key_0)
{
qDebug()<<"key_0 pressed"<<endl;
}
else
{
QWidget::keyPressEvent(event);
}
}
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
if(event->isAutoRepeat())
{
event->ignore();
}
else
{
if(event->key() == Qt::Key_0)
{
qDebug()<<"key_0 released"<<endl;
}
else
{
QWidget::keyReleaseEvent(event);
}
}
}

Но видимо isAutoRepeat функция не работает, так как я вижу непрерывную печать из key_0 pressed а также key_0 released несмотря на то, что я не отпустил клавишу 0 после того, как нажал ее. Мой код неправильный или что-то еще не так?

Благодарю.

РЕДАКТИРОВАТЬ

Я думаю, что это происходит потому, что MainWindow теряет фокус клавиатуры. Как я могу узнать, какой виджет имеет фокус? Я на самом деле использую некоторые виджеты, когда Qt::Key_0 нажал, но я думал, что я установил все эти возможные виджеты Qt::NoFocusЯ думаю, это не работает.

Я пытаюсь узнать, какой виджет имеет фокус, выполнив следующие действия:

QWidget * wigdet = QApplication::activeWindow();
qDebug()<<wigdet->accessibleName()<<endl;

но он всегда печатает пустую строку. Как я могу заставить его печатать название виджета, который имеет фокус клавиатуры?

0

Решение

Так что я также наткнулся на эту проблему (и grabKeyboard на самом деле не помог), я начал копаться в qtbase. Он подключен к X11 через xcb, и по умолчанию, в случае повторяющихся клавиш, X11 отправляет для каждого повторяющегося ключа событие освобождения, за которым сразу следует событие нажатия клавиши. Таким образом, удержание клавиши приводит к последовательности XCB_BUTTON_RELEASE / XCB_BUTTON_PRESS-событий, отправляемых клиенту (попробуйте это с xev или источником в конце эта страница).

Тогда qt (qtbase / SRC / плагины / платформы / XCB / qxcbkeyboard.cpp) из этих событий пытается выяснить, является ли это случаем автоматического повторения: когда получен релиз, он использует функцию упреждения, чтобы выяснить, следует ли за ним нажатие (с достаточно близкими временными метками), и если это так, он предполагает автоматическое повторение.

Это не всегда работает, по крайней мере, не на всех платформах. Для моего случая (старый и изношенный медленный ноутбук (Intel® Celeron® CPU N2830 @ 2,16 ГГц × 2) с Ubuntu 16.04), он помог просто поставить usleep (500) перед этой проверкой, позволяя событию press после выпуска прибытие события … оно находится вокруг строки 1525 файла qxcbkeyboard.cpp:

    // look ahead for auto-repeat
KeyChecker checker(source->xcb_window(), code, time, state);
usleep(500); // Added, 100 is to small, 200 is ok (for me)
xcb_generic_event_t *event = connection()->checkEvent(checker);
if (event) {
...

Подал это как QTBUG-57335.

Nb: поведение X может быть изменено с помощью

Display *dpy=...;
Bool result;
XkbSetDetectableAutoRepeat (dpy, true, &result);

Затем он не будет отправлять эти последовательности отпускания-нажатия в случае удерживающей клавиши, но для его использования потребуется больше изменений в логике автоматического повторения-обнаружения.

1

Другие решения

Все равно решил это.

Проблема заключалась в том, что у меня есть виджет, который является подклассом QGLWidget, который я использую для отображения некоторых изображений дополненной реальности из Kinect. Этот виджет принимает фокус клавиатуры при каждом нажатии кнопки клавиатуры.

Чтобы решить эту проблему, мне нужно было позвонить grabKeyboard функция от MainWindow учебный класс (MainWindow это подкласс QMainWindow), так this->grabKeyboard() это строка, которую мне нужно было добавить, когда key_0 кнопка нажата так, чтобы MainWindow не теряет фокус клавиатуры, а затем, когда клавиша отпущена, мне нужно было добавить строку this->releaseKeyboard() чтобы возобновить нормальное поведение, то есть другие виджеты могут иметь фокус клавиатуры.

0

По вопросам рекламы [email protected]