Читаем QT 4: программирование GUI на С++ полностью

События уведомляют объекты о себе при помощи своих функций event, унаследованных от класса QObject. Реализация event в QWidget передает большинство обычных событий конкретным обработчикам событий, например mousePressEvent, keyPressEvent и paintEvent.

Мы уже ознакомились в предыдущих главах со многими обработчиками событий при реализации MainWindow, IconEditor и Plotter. Существует много других типов событий, приводимых в справочной документации по QEvent, и можно также самому создавать и генерировать события. В данной главе мы рассмотрим два распространенных типа событий, заслуживающих более детального обсуждения, а именно события клавиатуры и события таймера.

События клавиатуры обрабатываются путем переопределения функций keyPressEvent и keyReleaseEvent. Виджет Plotter переопределяет keyPressEvent. Обычно нам требуется переопределить только keyPressEvent, поскольку отпускание клавиш важно только для клавиш—модификаторов, то есть для клавиш Ctrl, Shift и Alt, а их можно проконтролировать в keyPressEvent при помощи функции QKeyEvent::modifiers. Например, если бы нам пришлось реализовывать виджет CodeEditor (редактор программного кода), общий вид его функции keyPressEvent с различной обработкой клавиш Home и Ctrl+Home был бы следующим:

01 void CodeEditor::keyPressEvent(QKeyEvent *event)

02 {

03 switch (event->key) {

04 case Qt::Key_Home:

05 if (event->modifiers & Qt::ControlModifier) {

06 goToBeginningOfDocument;

07 } else {

08 goToBeginningOfLine;

09 }

10 break;

11 case Qt::Key_End:

12 …

13 default:

14 QWidget::keyPressEvent(event);

15 }

16 }

Клавиши Tab и Backtab (Shift+Tab) представляют собой особый случай. Они обрабатываются функцией QWidget::event до вызова keyPressEvent c установкой фокуса на следующий или предыдущий виджет в фокусной цепочке. Обычно нам нужен именно такой режим работы, но в виджете CodeEditor мы, возможно, предпочтем использовать клавишу табуляции Tab для обеспечения отступа в начале строки. Переопределение функции event выглядело бы следующим образом:

01 bool CodeEditor::event(QEvent *event)

02 {

03 if (event->type == QEvent::KeyFress) {

04 QKeyEvent *keyEvent = static_castevent;

05 if (keyEvent->key == Qt::Key_Tab) {

06 insertAtCurrentPosition('\t');

07 return true;

08 }

09 }

10 return QWidget::event(event);

11 }

Если событие сгенерировано нажатием клавиши клавиатуры, мы преобразуем объект типа QEvent в QKeyEvent и проверяем, какая клавиша была нажата. Если это клавиша Tab, мы выполняем некоторую обработку и возвращаем true, чтобы уведомить Qt об обработке нами события. Если бы мы вернули false, Qt передала бы cобытие родительскому виджету.

Высокоуровневый метод обработки клавиш клавиатуры заключается в применении класса QAction. Например, если goToBeginningOfLine и goToBeginningOfDocument являются открытыми слотами виджета CodeEditor и CodeEditor применяется в качестве центрального виджета класса MainWindow, мы могли бы обеспечить обработку клавиш при помощи следующего программного кода:

01 MainWindow::MainWindow

02 {

03 editor = new CodeEditor;

04 setCentralWidget(editor);

05 goToBeginningOfLineAction =

06 new QAction(tr("Go to Beginning of Line"), this);

07 goToBeginningOfLineAction->setShortcut(tr("Home"));

08 connect(goToBeginningOfLineAction, SIGNAL(activated),

09 editor, SLOT(goToBeginningOfLine));

10 goToBeginningOfDocumentAction =

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже