01 #include <QApplication>
02 #include "mainwindow.h"
03 int main(int argc, char *argv[])
04 {
05 QApplication app(argc, argv);
06 QStringList args = app.arguments();
07 MainWindow mainWin;
08 if (args.count() > 1) {
09 for (int i = 1; i < args.count(); ++i)
10 mainWin.openFile(args[i]);
11 } else {
12 mainWin.newFile();
13 }
14 mainWin.show();
15 return app.exec();
16 }
Еслй пользователь задает в командной строке какие-нибудь файлы, мы пытаемся их загрузить, в противном случае мы начинаем работу с пустым документом. Такие характерные для Qt опции командной строки, как —style и —font (стиль и шрифт), автоматически убираются из списка аргументов конструктором QApplication. Поэтому, если мы напишем в командной строке
mdieditor -style motif readme.txt
QApplication::arguments() возвратит QStringList с двумя элементами («mdieditor» и «readme.txt»), а МDI—приложение Editor запустится с документом readme.txt.
Интерфейс MDI представляет собой один из способов работы одновременно со многими документами. В системе MacOS Х более предпочтителен подход, связанный с применением нескольких окон верхнего уровня. Этот подход рассматривается в разделе «Работа со многими документами» главы З.
Глава 7. Обработка событий
События генерируются оконной системой или Qt в ответ на различные действия. Когда пользователь нажимает или отпускает клавишу или кнопку мышки, генерируется событие клавиши клавиатуры или кнопки мышки; когда окно впервые выводится на экран, генерируется событие рисования, указывая появившемуся окну на необходимость его прорисовки. Большинство событий генерируются в ответ на действия пользователя, но некоторые события, например, события таймера, генерируются самой системой и не зависят от действий пользователя.
При программировании в Qt нам редко приходится думать о событиях, поскольку виджеты Qt сами генерируют сигналы в ответ на любое существенное событие. События становятся полезными при создании нами своих сооственных виджетов, или когда мы хотим модифицировать поведение существующих виджетов Qt.
События не следует путать с сигналами. Как правило, сигналы полезны при uспользовании виджета, в то время как события полезны при реализации виджета. Например, при применении кнопки QPushButton мы больше заинтересованы в ее сигнале clicked(), чем в обработке низкоуровневых событий мышки или клавиатуры, сгенерировавших этот сигнал. Но если мы реализуем такой класс, как QPushButton, нам необходимо написать программный код для обработки событий мышки и клавиатуры и при необходимости сгенерировать сигнал clicked().
Переопределение обработчиков событий
В Qt событие (event) — это объект, производный от QEvent. Qt обрабатывает более сотни типов событий, каждое из которых идентифицируется определенным значением перечисления. Например, QEvent::type() возвращает QEvent::MouseButtonPress для событий нажатия кнопки мышки.
Для событий многих типов недостаточно тех данных, которые могут храниться в простом объекте QEvent: например, для событий нажатия кнопки мышки необходимо иметь информацию о том, какая кнопка мышки привела к возникновению данного события, а также о том, где находился курсор мышкй в момент возникновения события. Эта дополнительная информация хранится в определенных подклассах QEvent, например, в QMouseEvent.
События уведомляют объекты о себе при помощи своих функций 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 был бы следующим: