Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Система построения проектов CMake. Учебник.pdf
X
- •Введение
- •Модульное программирование
- •Автоматизация построения проектов
- •Обзор инструментов построения проектов
- •qmake
- •Генераторы
- •Входные файлы
- •Пути
- •Синтаксис
- •Команды
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Основные концепции
- •Строки
- •Свойства
- •Примеры простых проектов
- •Команды общего назначения
- •cmake_minimum_required()
- •project()
- •include()
- •message()
- •Команды описания целей
- •add_executable()
- •add_library()
- •add_subdirectory()
- •Команды настроек целей
- •include_directories()
- •target_include_directories()
- •add_definitions(), add_compile_options()
- •target_compile_definitions()
- •target_compile_options()
- •target_compile_features()
- •target_link_libraries()
- •add_dependencies()
- •Команды обработки данных
- •math()
- •list()
- •Команды управляющих конструкций
- •foreach(), endforeach()
- •Команды работы с файлами
- •get_filename_component()
- •Команды добавления специальных целей
- •configure_file()
- •add_test(), enable_testing()
- •install()
- •add_custom_target()
- •Прочие команды
- •find_package()
- •get_property(), set_property()
- •Виды конфигураций
- •Выражения генераторов
- •Информационные выражения
- •Логические выражения
- •Преобразующие выражения
- •Вспомогательные выражения
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Интерфейс подключения библиотек
- •Подключение заголовочной библиотеки
- •Частичная подмена стандартной библиотеки
- •Интерфейс подключения библиотек
- •Локализация приложения
- •Установка приложения
- •Инструменты разработки
- •Управление версиями
- •Генерирование документации
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Заключение
- •Библиография
- •Ответы на тесты

hкаталог проектаi
<qresource prefix="/general">
</qresource>
</RCC>
3.3. Qt
resources
qt.ico
ex-qt-qrc.cpp
ex-qt-qrc.qrc ... описание ресурсов, редактируется Qt Creator
CMakeLists.txt
Рис. 3.6. Структура каталога проекта с ресурсами
<file>resources/qt.ico</file>
Содержимое файла ex-qt-qrc.cpp:
#include <QApplication>
#include <QLabel>
#include <QIcon>
int main(int nArgC, char *apszArgV[])
{
QApplication app(nArgC, apszArgV);
QApplication::setWindowIcon(
QIcon(":/general/resources/qt.ico"));
//
QLabel label("Hello Qt!");
label.show();
//
return app.exec();
311

3. Примеры использования пакетов
}
Здесь статический метод QApplication::setWindowIcon()
устанавливает пиктограмму изображения, которая загружается
из файла с заданным путём. Двоеточие в начале означает,
что путь указывается относительно дерева ресурсов, хранимого
внутри исполняемого файла.
Файл CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.11)
project(ex-qt-qrc)
find_package(Qt5Widgets REQUIRED)
qt5_add_resources(
QRC_WRAPPERS ex-qt-qrc.qrc
OPTIONS -no-compress)
add_executable(
ex-qt-qrc WIN32
ex-qt-qrc.cpp ${QRC_WRAPPERS})
target_link_libraries(
ex-qt-qrc Qt5::Widgets)
Здесь в команде qt5_add_resources() определяются дополнительные аргументы командной строки, которые передаются инструменту qrc. Ключ -no-compress отключает сжатие
312

3.3. Qt
данных, выполняемое по умолчанию (алгоритм zlib10). Это может быть полезным для экономии времени построения, особенно если ресурсы уже находятся в сжатом виде (например, изображения в формате PNG).
В результате построения в выходном каталоге создаётся
файл qrc_ex-qt-qrc.cpp. Полный путь к нему на этапе исполнения CMake записывается в переменную QRC_WRAPPERS, которая затем используется в списке входных файлов цели в команде add_executable(). ∗
Замечание: при помощи других ключей инструмента qrc мож-
но настроить уровень сжатия от 1 до 9 (-compress hуровеньi)
и пороговое отношение сжатого размера к исходному (в процентах), начиная с которого файл будет помещён в ресурсы в несжатом виде (-threshold hотношениеi).
N
Другим инструментом Qt, для которого также есть поддержка в CMake, является компилятор пользовательского ин-
терфейса (User Interface Compiler, uic). Текст реализации главного окна в примере на с. 305 показывает, что даже отображение
меню из двух команд вынуждает разработчика писать множество строк кода, не говоря уже о программировании сложных
диалоговых окон с большим количеством графических элементов управления. Для облегчения этих задач в Qt используется
визуальный редактор Qt Designer (или Qt Creator), при помощи
которого можно «нарисовать» окна с требуемыми элементами
управления, размерами и другими свойствами. Вся информация сохраняется в текстовом файле с расширением «.ui», имею-
10
http://www.zlib.net/ (дата обращения: 05.03.2015).
313

3. Примеры использования пакетов
щем структуру XML. В процессе построения компилятор пользовательского интерфейса по этому файлу генерирует в выходном
каталоге заголовочный файл, содержащий весь код инициализации внешнего вида окна (рис. 3.7).
Qt Designer
mydlg.ui
uic
Рис. 3.7. Преобразование описания ресурса в код на C
ui_mydlg.h
++
при помощи инструмента uic
В CMake для создания правил вызова компилятора пользовательского интерфейса существует команда qt5_wrap_ui(),
которая определяется после успешного поиска пакета
Qt5Widgets. Её синтаксис аналогичен двум предыдущим
командам:
qt5_wrap_ui(
hимя_переменнойi
hфайл_интерфейса1i ... hфайл_интерфейсаmi
f
OPTIONS hаргумент1i ... hаргументnig)
ПРИМЕР
Пусть при помощи инструмента Qt Designer создан макет диалогового окна (рис. 3.8), которое необходимо использовать в качестве основного модального окна приложения.
314

3.3. Qt
Рис. 3.8. Редактирование файла пользовательского
интерфейса при помощи инструмента Qt Designer
Для удобства дальнейшей работы над проектом можно создать заголовочный файл с описанием класса окна
(InputDialog). Таким образом, структура каталога проекта будет такой, как на рис. 3.9.
Содержимое файла input_dialog.h:
#ifndef INPUT_DIALOG_H__
#define INPUT_DIALOG_H__
#include "ui_input_dialog.h"
#include <QDialog>
315

3. Примеры использования пакетов
hкаталог проектаi
ex-qt-uic.cpp ......................................... main()
input_dialog.cpp
input_dialog.h .........описание класса окна InputDialog
CMakeLists.txt
input_dialog.ui .................редактируется Qt Designer
Рис. 3.9. Структура каталога проекта с описанием
пользовательского интерфейса
class InputDialog :
public QDialog, public Ui::InputDialog
{
public:
//
InputDialog(QWidget *pParent = 0);
};
#endif // INPUT_DIALOG_H__
Здесь заголовочный файл ui_input_dialog.h генерируется в каталоге построения инструментом uic на основе содержимого файла пользовательского интерфейса input_dialog.ui.
В нём определён класс Ui::InputDialog, отвечающий за внешний вид окна.
Файл input_dialog.cpp с реализацией конструкцией класса InputDialog:
#include "input_dialog.h"
316

3.3. Qt
InputDialog::InputDialog(QWidget *pParent)
: QDialog(pParent)
{
setupUi(this);
}
Здесь метод setupUi(), унаследованный от сгенерированного класса Ui::InputDialog, исполняет весь код инициализации окна.
Файл ex-qt-uic.cpp:
#include "input_dialog.h"
#include <QApplication>
int main(int nArgC, char *apszArgV[])
{
QApplication app(nArgC, apszArgV);
InputDialog dialog;
dialog.exec();
}
Файл CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.11)
project(ex-qt-uic)
317

3. Примеры использования пакетов
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets REQUIRED)
qt5_wrap_ui(
UI_WRAPPERS input_dialog.ui)
add_executable(
ex-qt-uic WIN32
ex-qt-uic.cpp input_dialog.cpp input_dialog.h
${UI_WRAPPERS})
target_link_libraries(
ex-qt-uic Qt5::Widgets)
Здесь значение истины присваивается специальной переменной CMake CMAKE_INCLUDE_CURRENT_DIR, чтобы каталог построения добавлялся в список путей для поиска заголовочных
файлов. Это необходимо для того, чтобы директива #include, которая подключает файл ui_input_dialog.h и которая использована в файле input_dialog.h, сработала правильно. ∗
Замечание: в целях сокращения объёма примера в нём отсут-
ствует код обработки событий пользовательского интерфейса
на основе сигналов и слотов. В реальных проектах в классах окон определяются слоты. Следовательно, эти классы также нужно передавать компилятору метаинформации при помощи команды qt5_wrap_cpp(), аналогично примеру на с. 305
(см. также следующий пример).
318
N

3.3. Qt
В качестве альтернативы приведённым выше командам
qt5_...() можно присвоить значения истины специальным
переменным CMAKE_AUTOMOC (доступна в CMake начиная с версии 2.8.6), CMAKE_AUTORCC и CMAKE_AUTOUIC (доступны начиная с 3.0). Этими переменными инициализируются соответствующие свойства целей, которые включают генерирование
специальных правил построения, автоматически определяющих необходимость запуска инструментов для нужных файлов. Анализ исходных текстов учитывает директивы подклю-
чения заголовочных файлов с именами ui_....h и т. д. Под-
держиваются Qt версий 4 и 5. При использовании этих режимов упрощается описание проекта и добавление новых исходных файлов, однако несколько замедляется процесс построения.
Для передачи инструментам moc и т. д. дополнительных ключей командной строки можно использовать специальные переменные CMAKE_AUTOMOC_MOC_OPTIONS, CMAKE_AUTORCC_OPTIONS
и CMAKE_AUTOUIC_OPTIONS.
ПРИМЕР
Пусть требуется добавить к предыдущему примеру (с. 314) обработку событий ввода: реализовать для пользователя возможность нажать кнопку «OK» только в том случае, если оба текстовых поля ввода заполнены непустыми значениями. Пусть также требуется добавить к диалоговому окну пиктограмму, аналогично примеру на с. 310. Структура каталога проекта, таким
образом, будет выглядеть так, как на рис. 3.10.
Файл input_dialog.h:
319

3. Примеры использования пакетов
hкаталог проектаi
resources
qt.ico
ex-qt-auto.cpp ........................................main()
input_dialog.cpp
input_dialog.h ........................обрабатывается moc
ex-qt-auto.qrc .........................обрабатывается rcc
CMakeLists.txt
input_dialog.ui ........................обрабатывается uic
Рис. 3.10. Структура каталога проекта с автоматическим
запуском инструментов Qt
#ifndef INPUT_DIALOG_H__
#define INPUT_DIALOG_H__
#include "ui_input_dialog.h"
#include <QDialog>
class InputDialog :
public QDialog, public Ui::InputDialog
{
Q_OBJECT
//
public:
//
InputDialog(QWidget *pParent = 0);
//
private slots:
320
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
