QT 4: программирование GUI на С++
Шрифт:
Одна из особенностей классов менеджеров компоновки заключается в том, что они не являются виджетами. Взамен этого они наследуют свойства класса QLayout, который, в свою очередь, является наследником класса QObject. На данном рисунке виджеты выделены сплошными линиями, а менеджеры компоновки очерчены пунктирными линиями, чтобы подчеркнуть их различие. При работе приложения менеджеры компоновки невидимы.
При добавлении внутренних менеджеров компоновки к родительскому менеджеру компоновки (строки 25, 33 и 34) для них автоматически устанавливается родительская связь. Затем, когда главный менеджер компоновки устанавливается для диалога (строка 35),
Рис. 2.3. Родословная объектов диалогового окна поиска данных.
Наконец, мы задаем название диалогового окна и устанавливаем фиксированной его высоту, поскольку в диалоговом окне нет виджетов, которым может понадобиться дополнительное пространство по вертикали. Функция QWidget::sizeHint возвращает «идеальный» размер виджета.
На этом завершается рассмотрение конструктора FindDialog. Поскольку нами использован оператор new при создании виджетов и менеджеров компоновки, нам, по-видимому, придется написать деструктор, где будут предусмотрены операторы delete для удаления каждого созданного нами виджета и менеджера компоновки. Но поступать так не обязательно, поскольку Qt автоматически удаляет дочерние объекты при разрушении родительского объекта, а все дочерние виджеты и менеджеры компоновки являются потомками FindDialog.
Теперь мы рассмотрим слоты диалогового окна:
Слот findClicked вызывается при нажатии пользователем кнопки Find. Он генерирует сигнал findPrevious или findNext в зависимости от состояния флажка Search backward (поиск в обратном направлении). Ключевое слово emit (генерировать сигнал) имеет особый смысл в Qt; как и другие расширения Qt, оно преобразуется препроцессором С++ в стандартные инструкции С++.
Слот enableFindButton вызывается при любом изменении значения в строке редактирования. Он устанавливает активный режим кнопки, если в редактируемой строке имеется
Эти два слота завершают написание программы диалогового окна. Теперь мы можем создать файл main.cpp и протестировать наш виджет FindDialog:
Для компиляции этой программы выполните обычную команду qmake. Поскольку определение класса FindDialog содержит макрос Q_OBJECT, сформированный командой qmake, файл makefile будет содержать специальные правила для запуска moc — мета—объектного компилятора Qt. (Мета—объектная система Qt рассматривается в следующем разделе.)
Для правильной работы moc мы должны включить определение класса в заголовочный файл, то есть отделить его от файла реализации класса. Сформированный moc программный код содержит этот заголовочный файл и собственно сгенерированные инструкции С++.
Классы с макросом Q_OBJECT сначала должны пройти через компилятор moc. Здесь не будет проблем, поскольку qmake автоматически добавляет в файл makefile необходимые команды. Однако если вы забудете сгенерировать файл makefile командой qmake, программа не пройдет через компилятор moc и компоновщик программы пожалуется на то, что некоторые объявленные функции не реализованы. Эти сообщения могут выглядеть достаточно странно. GCC выдает сообщения следующего вида:
Сообщения в Visual С++ выглядят следующим образом:
При появлении подобных сообщений снова выполните команду qmake для обновления файла makefile, затем заново постройте приложение.