Игнорировать нажатия клавиш на Qt внутри OSG

Я новичок в Qt и столкнулся с одной проблемой, с которой не могу справиться уже месяц. Ситуация такова: у меня есть проект OpenSceneGraph (который является OpenGL) и я пытаюсь сделать интерфейс Qt внутри 3D-сцены. Я думаю, что это не обязательно, как я с этим справлюсь, но если кто-то хочет узнать больше, здесь — это ветка с дополнительной информацией на форуме OSG (хотя я не нашел там решения). Проблема в том, что при нажатии любой клавиши на клавиатуре элементы управления Qt прыгают по экрану и больше не реагируют ни на какие события (мыши или клавиатуры). При этом вся программа продолжает работать. Подводя итог, мой вопрос звучит так: есть ли способ заставить виджеты Qt игнорировать все нажатия клавиш? Я много искал, но не смог найти работающего решения.

Заранее спасибо!


person Kilazi    schedule 17.10.2012    source источник


Ответы (1)


Прочтите немного о событиях в Qt. Есть раздел о фильтрации событий (но, пожалуйста, не переходите сразу к нему :P).

КРАТКИЙ ОТВЕТ:

void Qwidget::setEnabled ( bool );

Недостатком является то, что он также отключает события мыши, меняет стиль виджета, и это облом.

ДЛИННЫЙ ОТВЕТ: ФИЛЬТР СОБЫТИЙ

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

int main(int argc, char* argv[]){
    QApplication app(argc, argv);
    QWidget toplevelwidget1;
    toplevelwidget1.show()
    //stufff
    return app.exec();
} 
//doesnt have to exactly like this.

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

Вместо этого вы можете отфильтровать только виджеты или окна верхнего уровня (без родителей). Вы определяете фильтр событий (который представляет собой QObject), например:

class KeyboardFilter: public QObject
{
   Q_OBJECT
   ...

   protected:
     bool eventFilter(QObject *obj, QEvent *event);
 };

  bool KeyboardFilter::eventFilter(QObject *obj, QEvent *event)
  {
      //for all events from keyboard, do nothing
      if (event->type() == QEvent::KeyPress || 
          event->type() == QEvent::KeyRelease ||
          event->type() == QEvent::ShortcutOverride ||
          ) {
          return true;
      } else {
        // for other, do as usual (standard event processing)
        return QObject::eventFilter(obj, event);
      }
  }

Затем вы устанавливаете фильтр на нужные виджеты, используя:

 myDesiredWidgetorObject->installEventFilter(new KeyboardFilter(parent));

Вот и все!

person UmNyobe    schedule 17.10.2012
comment
Спасибо за быстрый ответ. Я прочитал статью и попробовал ваше решение с длинным ответом. Хотя это не сработало, возможно, я что-то упускаю: что имеется в виду в вашем ... в объявлении класса? И еще, почему у нового KeyboardFilter(parent) есть какой-то родитель, если он предназначен для использования с виджетами, у которых нет родителя? :P Еще меня смущает один момент: нажатие клавиши заставляет виджет прыгать в одно место экрана не симулировано, а по одному (один щелчок - кнопка прыгает, другой щелчок - другая кнопка прыгает на предыдущую). В любом случае, спасибо за этот ответ, по крайней мере, теперь мне есть чему поучиться! - person Kilazi; 17.10.2012
comment
Не сработало? Я предложил идею решения, а не что-то, что будет напрямую компилироваться и работать... Одно из решений - быть консервативным и использовать этот фильтр для всех виджетов, которые вы создаете, независимо от верхнего уровня или нет. Это should работает. - person UmNyobe; 17.10.2012
comment
1) ... — это просто способ сказать бла-бла-бла. 2) Родительская вещь - это отдельная концепция, а KeyboardFilter является подклассом QObject, поэтому у него может быть родитель. Теперь вы можете установить его равным нулю, если хотите, но это зависит от вашего кода. Не имеет значения, есть ли у виджетов родитель или нет... 3) эти button jumps действительно странные, ничего нельзя сказать, не видя исходный код. - person UmNyobe; 17.10.2012
comment
Интересный факт: даже когда я устанавливаю widget-›setEnabeled(false) и нажимаю кнопку на клавиатуре, все равно возникает та же ошибка. Поэтому я не думаю, что что-то, что я могу сделать с виджетом, поможет. - person Kilazi; 18.10.2012