Добавил:
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()
- •Виды конфигураций
- •Выражения генераторов
- •Информационные выражения
- •Логические выражения
- •Преобразующие выражения
- •Вспомогательные выражения
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Интерфейс подключения библиотек
- •Подключение заголовочной библиотеки
- •Частичная подмена стандартной библиотеки
- •Интерфейс подключения библиотек
- •Локализация приложения
- •Установка приложения
- •Инструменты разработки
- •Управление версиями
- •Генерирование документации
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Заключение
- •Библиография
- •Ответы на тесты

#include <QtConcurrent>
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
typedef std::vector <int> IntVector;
void print(const IntVector &rcVector)
{
3.3. Qt
std::copy(
rcVector.begin(), rcVector.end(),
std::ostream_iterator <int> (std::cout, " "));
std::cout << std::endl;
}
int main(int nArgC, char *apszArgV[])
{
QApplication app(nArgC, apszArgV);
//
IntVector v1;
for (int i = 0; i < 30; ++ i)
v1.push_back(i);
print(v1);
//
IntVector v2 =
301

3. Примеры использования пакетов
QtConcurrent::blockingMapped <IntVector> (
v1, std::negate <int> ());
print(v2);
}
Файл CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.11)
project(ex-qt-concurrent)
find_package(Qt5 REQUIRED Widgets Concurrent)
add_executable(
ex-qt-concurrent ex-qt-concurrent.cpp)
target_link_libraries(
ex-qt-concurrent Qt5::Widgets Qt5::Concurrent)
Собранное приложение будет зависеть от библиотеки
Qt5Concurrent.dll (или Qt5Concurrentd.dll), помимо
перечисленных в табл. 3.6. ∗
Замечание: при подключении других библиотек Qt для запус-
ка скомпилированного приложения могут также понадобиться
файлы разделяемых модулей этих библиотек (Qt5Multimedia,
Qt5Network и т. д.), а также библиотека libwinpthread-1.dll,
которая реализует в компиляторе gcc-MinGW интерфейс POSIX
Threads.
302
N

3.3. Qt
3.3.2. Использование инструментов Qt
В процессе построения проектов, в которых используется Qt, приходится выполнять вызовы вспомогательных инструментов, генерирующих исходные коды [1; 8]. Одним из таких инструментов является компилятор метаобъектов (Meta-
Object Compiler, moc), который реализует технологию метапрограммирования, используемую в Qt. Он анализирует заголовочные файлы проекта, в которых описаны классы, производные
от QObject (базы иерархии классов Qt), и записывает в выходной cpp-файл код, который реализует поддержку отсутствующей в языке C++интроспекции. На её основе реализуются различные механизмы Qt, такие как технология обмена сообщениями при помощи сигналов и слотов. Если разработчику нужна поддержка каких-либо из этих возможностей в его классах,
он оформляет их соответствующим образом (добавляет макрос
Q_OBJECT, распознаваемый инструментом moc, в объявление
класса и т. д.):
#include <QObject>
class MyObject : public QObject
{
Q_OBJECT
// ...
private slots:
//
void slot1();
303

3. Примеры использования пакетов
// ...
};
Кроме этого, необходимо обеспечить запуск инструмента
moc для заголовочного файла с его объявлением во время построения проекта (рис. 3.2).
myobject.h
moc
moc_myobject.cpp
Рис. 3.2. Генерирование метаинформации при помощи
инструмента moc
В системе CMake для этих целей используется команда
qt5_wrap_cpp(), которая становится доступной после нахождения библиотеки Core при помощи команды find_package():
qt5_wrap_cpp(
hимя_переменнойi
hзаголовочный_файл1i ... hзаголовочный_файлmi
f
OPTIONS hаргумент1i ... hаргументnig)
Команда создаёт правила для генерирования файлов в вы-
ходном каталоге из заданных заголовочных файлов проекта.
Список путей к генерируемым файлам в каталоге построения
записывается в заданную переменную, которую затем можно
использовать в команде add_executable() для их добавления
к цели. После необязательного аргумента OPTIONS можно указать дополнительные ключи командной строки для передачи
инструменту moc. Команда также добавляет для каталога текущего подпроекта все необходимые определения препроцессора.
304

3.3. Qt
ПРИМЕР
Пусть требуется создать приложение с оконным пользовательским интерфейсом, в главном меню которого находятся команды «Открыть файл» и «Выход» (рис. 3.3). Выбор пользователем
первой команды должен приводить к отображению диалогового окна для запроса имени текстового файла, второй — к закрытию программы.
Рис. 3.3. Оконное приложение с меню, использующее
библиотеки Qt
Заголовочный файл с объявлением класса главного окна
приложения (main-window.h):
#ifndef MAIN_WINDOW_H__
#define MAIN_WINDOW_H__
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
//
public:
305

3. Примеры использования пакетов
//
MainWindow(QWidget *pParent = 0);
//
private slots:
//
void onFileOpen();
};
#endif // MAIN_WINDOW_H__
Файл реализации главного окна (main-window.cpp):
#include "main-window.h"
#include <QMenuBar>
#include <QKeySequence>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *pParent)
: QMainWindow(pParent)
{
QMenu *pMenuFile = menuBar()->addMenu(tr("&File"));
pMenuFile->addAction(
tr("&Open..."), this,
SLOT(onFileOpen()), QKeySequence::Open);
pMenuFile->addAction(
tr("E&xit"), this,
SLOT(close()), QKeySequence::Quit);
306

3.3. Qt
}
void MainWindow::onFileOpen()
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Open File"), "", tr("Text Files (*.txt)"));
}
Поскольку в классе основного окна определена функция
onFileOpen(), работающая в качестве слота, в определение
класса добавляется макрос Q_OBJECT. В описании проекта необходимо указать правила, по которым при помощи инструмента
moc в каталоге построения должен генерироваться файл метаинформации о классе MainWindow, который должен участвовать
в построении приложения.
Точка входа в программу (файл ex-qt-moc.cpp):
#include "main-window.h"
#include <QApplication>
int main(int nArgC, char *apszArgV[])
{
QApplication app(nArgC, apszArgV);
MainWindow window;
window.show();
return app.exec();
307

3. Примеры использования пакетов
}
Файл CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.11)
project(ex-qt-moc)
find_package(Qt5Widgets REQUIRED)
set(HEADERS main-window.h)
qt5_wrap_cpp(MOC_FILES ${HEADERS})
add_executable(
ex-qt-moc WIN32
ex-qt-moc.cpp main-window.cpp
${HEADERS} ${MOC_FILES})
target_link_libraries(
ex-qt-moc Qt5::Widgets)
Во время построения в выходном каталоге создаётся файл
moc_main-window.cpp по содержимому приведённого выше
файла main-window.h. Полный путь к генерируемому файлу
записывается в переменную MOC_FILES и затем используется
в списке входных файлов в команде add_executable(). ∗
Аналогичным образом в CMake реализована поддержка
компилятора ресурсов Qt (Resource Compiler, rcc). Этот инстру-
мент используется для встраивания в исполняемые файлы дво-
308

3.3. Qt
ичных данных, таких как изображения и пиктограммы, отображаемые пользовательским интерфейсом. В отличие от похожего механизма в системе Windows, Qt реализует поддержку
ресурсов кроссплатформенным способом: преобразованием двоичных файлов в текст на языке C++с объявлениями массивов.
Для описания ресурсов применяются текстовые файлы с расширением «.qrc», использующие язык XML и редактируемые средой разработки Qt Creator (рис. 3.4).
Qt Creator
mydata.qrc
image1.ico
image2.jpg
. . .
rcc
qrc_mydata.cpp
Рис. 3.4. Генерирование ресурсов при помощи
инструмента rcc
Для добавления вызовов компилятора ресурсов в набор
правил построения в CMake используется команда:
qt5_add_resources(
hимя_переменнойi
hфайл_описания_ресурсов1i ... hфайл_описания_ресурсовmi
f
OPTIONS hаргумент1i ... hаргументnig)
309

3. Примеры использования пакетов
ПРИМЕР
Пусть требуется добавить отображаемую пиктограмму к основному окну приложения из примера на с. 298. Для этого сначала
необходимо поместить файл с изображением в каталог проекта,
допустим в подкаталог resources. Далее следует создать файл
описания ресурсов, например использовав инструмент Qt Creator (рис. 3.5).
Рис. 3.5. Редактирование файла описания ресурсов
при помощи среды разработки Qt Creator
Таким образом, структура каталога проекта будет такой,
как изображена на рис. 3.6.
Содержимое сгенерированного инструментом Qt Creator
файла ex-qt-qrc.qrc:
<RCC>
310
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
