Russian Qt Forum
Сентябрь 30, 2024, 22:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вопросы по навигации по виджетам с помощью клавиатуры  (Прочитано 2505 раз)
tim474
Гость
« : Январь 31, 2010, 04:28 »

Возможно вопрос тупой, но документация по Qt слишком обширная, поэтому сразу найти нужное затруднительно, тем более языковой барьер мешает. А я только начал учиться программированию с использованием Qt.
Допустим, я хочу написать программу, управляемую только с помощью клавиатуры, геймпада или пульта ДУ. Для начала возникает проблема навигации по виджетам, в частности, "ползункам" QSlider и Phonon::VolumeSlider. Я хочу, чтобы, допустим, клавишами up и down переключался виджет, на котором фокус, а кнопками left и right непосредственно передвигать эти слайдеры.
На предмет чего изучать документацию, чтобы сделать это?
Записан
DS_tm
Гость
« Ответ #1 : Январь 31, 2010, 13:03 »

У каждого виджета есть протектные виртуальные функции обработки сообщений, к примеру:

Код
C++ (Qt)
virtual void keyPressEvent ( QKeyEvent * event )
virtual void keyReleaseEvent ( QKeyEvent * event )
virtual void mouseDoubleClickEvent ( QMouseEvent * event )
virtual void mouseMoveEvent ( QMouseEvent * event )
virtual void mousePressEvent ( QMouseEvent * event )
virtual void mouseReleaseEvent ( QMouseEvent * event )
 

Соответстыенно можно переопределить нужную функцию, и используя функции QEvent классов (QKeyEvent::key()) понять, что нажал пльзователь.

Альтернативный вариант, это фильтрация сообщений, с помощью функций QObject::installEventFilter(), QObject::eventFilter().

По поводу фокуса, тут тоже есть два варианта: во-первых можно вызвать функцию setFocus() для виджета, на который должен перейти фокус; во-вторых можно вызвать в родительсом виджете функцию focusNextChild (), но при этом должна быть правильно расставлена последовательность табов (мне этот вариант кажеться более правильным, так как не меняет логики интерфейса).
Записан
SABROG
Гость
« Ответ #2 : Январь 31, 2010, 14:32 »

В качестве альтернативного варианта можно посмотреть в сторону QStateMachine, а именно на классы QKeyEventTransition или QEventTransition. Несмотря на кажущийся оверхед и возможность пойти простым путем используя переопределение keyPressEvent у подхода состояний есть преимущество. Если зажать какую-либо клавишу, то keyPressEvent будет вызываться очень часто, при этом как определить, что это не мы так часто долбим по клавише, а просто зажали кнопку и держим? Из-за того, что QStateMachine разделяет состояния после первого же нажатия на кнопку будет установлено новое состояние, при этом последующие приходы QKeyEvent (если мы зажали кнопку) будут естественно проигнорированы. В случае с переопределением keyPressEvent() пришлось бы каждый раз проверять какую команду обрабатывает в данный момент наша программа (если предположить многопоточный вариант приложения), а если однопоточный, то при долгой обработки одного нажатия (при зажатой клавише) в очереди их скопится столько, что на экране можно будет наблюдать медленное перемещение чего-либо (выделения, элемента), которое нельзя будет остановить нажав клавишу влево например, если перемещение идет вправо. Т.е. это как скользить по льду, ты разогнался и скользишь, а обратно скользить сможешь только когда достигнешь конца или не остановишься под силой трения. Такое поведение очень часто можно наблюдать в винде, когда она дико тормозит. Ты выбрал элемент меню и зажал вниз, чтобы выбрать другой элемент, а ничего не происходит (выделение не двигается), а когда винда отлагает ты начинаешь наблюдать анимацию - все что ты нажимал, кликал - все начинает обрабатываться и остановить это нельзя.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.152 секунд. Запросов: 20.