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

3.3. Qt
//
void on_lineEdit_textChanged();
};
#endif // INPUT_DIALOG_H__
Если указатель на первое поле ввода формы (рис. 3.8)
называется lineEdit (определяется в редакторе Qt Designer),
по правилам Qt объявленный в классе окна слот с именем
on_lineEdit_textChanged() будет автоматически связан с сигналом textChanged(), поступающим от объекта, на который
указывает lineEdit, всякий раз, когда содержимое поля ввода
изменяется.
Файл input_dialog.cpp:
#include "input_dialog.h"
#include <QPushButton>
InputDialog::InputDialog(QWidget *pParent)
: QDialog(pParent)
{
setupUi(this);
//
connect(
lineEdit_2, SIGNAL(textChanged(const QString &)),
this, SLOT(on_lineEdit_textChanged()));
//
321

3. Примеры использования пакетов
on_lineEdit_textChanged();
}
void InputDialog::on_lineEdit_textChanged()
{
QPushButton *pButton = buttonBox->button(
QDialogButtonBox::Ok);
pButton->setEnabled(
!lineEdit->text().isEmpty() &&
!lineEdit_2->text().isEmpty());
}
Здесь в конструкторе сначала происходит связывание того же слота on_lineEdit_textChanged() с тем же сигналом
textChanged(), но уже от второго поля ввода (lineEdit_2).
Дальше этот метод вызывается непосредственно, чтобы состояние диалогового окна соответствовало его начальному содержимому с момента его создания. В самом обработчике происходит
обращение к кнопке «OK» в группе buttonBox (создаётся в редакторе), для которой состояние доступности для нажатия определяется в зависимости от непустоты обоих полей ввода.
Файл ex-qt-auto.cpp:
#include "input_dialog.h"
#include <QApplication>
#include <QIcon>
322

3.3. Qt
int main(int nArgC, char *apszArgV[])
{
QApplication app(nArgC, apszArgV);
QApplication::setWindowIcon(
QIcon(":/general/resources/qt.ico"));
InputDialog dialog;
dialog.exec();
}
Содержимое файла описания ресурсов (ex-qt-auto.qrc)
и пользовательского интерфейса (input_dialog.ui) здесь имеют то же содержание, что и соответствующие файлы в двух
предыдущих примерах.
Файл CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(ex-qt-auto)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC_OPTIONS -no-compress)
find_package(Qt5Widgets REQUIRED)
add_executable(
323

3. Примеры использования пакетов
ex-qt-auto WIN32
ex-qt-auto.cpp ex-qt-auto.qrc
input_dialog.cpp input_dialog.h)
target_link_libraries(
ex-qt-auto Qt5::Widgets)
Здесь вначале запрашивается совместимость c CMake
версии 3.0, так как именно с неё доступны переменные
CMAKE_AUTORCC и CMAKE_AUTOUIC. Для того чтобы вызов инструмента rcc мог выполняться автоматически, необходимо, чтобы
файл описания ресурсов (ex-qt-auto.qrc) был добавлен к цели
исполняемого файла (команда add_executable()). ∗
3.3.3. Локализация приложения
Qt имеет встроенную поддержку простой в использовании
системы многоязычного пользовательского интерфейса с возможностью переключения языка приложения «на лету». Чтобы заменить в работающей программе все зависящие от языка сообщения для заданного перевода, необходимо при помощи
специального программного интерфейса Qt загрузить соответствующий языковой модуль из двоичного файла с расширением «.qm». Схема подготовки таких файлов для приложения приведена на рис. 3.11.
Первым используется инструмент lupdate, задача которого
заключается в сборе из исходных текстов всех строк, которые
видны пользователю. На вход ему подаются файлы описания
пользовательского интерфейса (с расширением «.ui»), а также
324

3.3. Qt
src1.cpp
src2.ui
. . .
lupdate
Qt Linguist
app_ru.ts
lrelease
app_ru.qm
Рис. 3.11. Создание файлов локализации при помощи
инструментов lupdate и lrelease
исходные модули и заголовочные файлы. Поддерживаются языки C++, Java и т. д. В исходных текстах все необходимые строковые литералы помещаются в вызовы функции QObject::tr()
и других подобных функций и макросов, которые служат двум
целям. Во-первых, с их помощью инструменту lupdate, который
проводит синтаксический анализ кода, указывается, какие строки требуют перевода. Во-вторых, во время выполнения программы они реализуют саму подмену строк.
Результатом работы инструмента lupdate является текстовый файл с расширением «.ts» (от «Translation Source»). Этот
файл имеет формат XML и содержит все собранные строки вместе с их местоположением в исходном коде, контекстом использования и комментариями для переводчика. Дальше переводчик интерфейса может использовать инструмент Qt Linguist для визуального редактирования этого файла (см. пример далее). Изначально каждая строка в нём имеет состояние
«не завершено», которое меняется после заполнения поля пере-
вода. Что важно, файл «.ts» является одновременно выходным
и входным для инструмента lupdate: если повторно запустить
325

3. Примеры использования пакетов
его для изменившихся исходных кодов, он добавит в файл новые данные, оставив нетронутыми уже переведённые строки.
Последним в цепочке инструментов используется lrelease,
который компилирует текстовый файл «.ts» в двоичный «.qm».
Для автоматизации построения файлов перевода в проекте средствами CMake инструментарий Qt предоставляет конфигурационный файл модуля LinguistTools, который определяет
следующую команду:
qt5_create_translation(
hимя_переменнойi
hпуть1i ... hпутьmi
f
OPTIONS hаргумент1i ... hаргументnig)
Эта команда определяет в текущем подпроекте правила
(при помощи команды add_custom_command(), п. 2.10.5) для ге-
нерирования файлов TS и QM. В переменную, имя которой передаётся первым аргументом, записываются полные пути к создаваемым результирующим QM-файлам. Эти пути можно передавать затем командам создания целей (add_executable() и т. д.)
в качестве исходных файлов, чтобы построение цели при необ-
ходимости вызывало и правила создания этих файлов. В каче-
стве альтернативы можно использовать эти пути как зависимости для цели, создаваемой командой add_custom_target()
(п. 2.10.4), чтобы файлы перевода можно было генерировать
запуском отдельной фальшивой цели. Особенностью команды
по сравнению с другими подобными является то, что часть генерируемых файлов (TS) создаётся в каталоге проекта рядом с ис-
326

3.3. Qt
ходными файлами вместо каталога построения. Это может потенциально создавать некоторые проблемы (см. пример ниже).
В качестве аргументов путей команде передаются:
— исходные файлы проекта, которые нужно обработать ко-
мандой lupdate;
— каталоги проекта, которые передаются команде lupdate
для поиска исходных файлов для обработки;
— пути к генерируемым промежуточным файлам TS.
Относительные пути к исходным файлам и файлам TS интерпретируются по отношению к каталогу подпроекта. Конечные файлы QM создаются в каталоге построения текущего подпроекта или, если для соответствующего ему TS-файла определено значение свойства OUTPUT_LOCATION, в определяемом им
каталоге.
После необязательного аргумента OPTIONS можно указать
дополнительные аргументы командной строки для инструмента lupdate.
Следующая команда добавляет только правила для построения QM-файлов из существующих TS-файлов при помощи инструмента lrelease:
qt5_add_translation(
hимя_переменнойi
hTS-файл1i ... hTS-файлmi)
Здесь передаваемое имя переменной имеет тот же смысл,
что и для предыдущей команды.
327

3. Примеры использования пакетов
ПРИМЕР
Пусть требуется реализовать приложение, которое выводит сообщение в простом диалоговом окне, при этом заголовок окна
и само сообщение должны быть выведены на языке, установленном в качестве системного. Эту задачу выполняет следующий код (файл ex-qt-translate.cpp):
#include <QApplication>
#include <QTranslator>
#include <QMessageBox>
int main(int nArgC, char *apszArgV[])
{
QApplication app(nArgC, apszArgV);
//
QTranslator translator;
const bool cbLoaded = translator.load(
QLocale::system(), "ex-qt-translate_");
if (cbLoaded)
app.installTranslator(&translator);
//
QMessageBox::information(
0,
QApplication::translate(
"main", "Application"),
QApplication::translate(
"main", "A localized message"));
} // main()
328

3.3. Qt
Здесь вначале создаётся объект типа QTranslator, при помощи которого производится попытка загрузить файл перевода с именем «ex-qt-translate_hязыкi.qm» в рабочем каталоге. В случае успеха этот объект устанавливается в качестве объекта локализации приложения. Дальше выводится сообщение функцией QMessageBox::information(). Передаваемые ей сообщение и заголовок обёрнуты в вызовы функции QCoreApplication::translate(), которая и выполняет
подмену строк в соответствии с установленным объектом
QTranslator.
Файл CMakeLists.txt, который определяет правила создания файла перевода для русского языка (приводимая схема в целом соответствует рекомендациям на Wiki-странице проекта
CMake11):
cmake_minimum_required(VERSION 2.8.11)
project(ex-qt-translate)
find_package(Qt5 REQUIRED Widgets LinguistTools)
set(
FILES_TO_TRANSLATE
ex-qt-translate.cpp)
set(
TS_FILES
11
http://www.cmake.org/Wiki/CMake:How_To_Build_Qt4_Software
10.03.2015).
(дата обращения:
329

3. Примеры использования пакетов
translations/ex-qt-translate_ru_RU.ts)
option(
UPDATE_TRANSLATIONS
"Update source translation (translations/*.ts)."
ON)
if(UPDATE_TRANSLATIONS)
message(
STATUS "UPDATE_TRANSLATIONS option is set.")
qt5_create_translation(
QM_FILES ${FILES_TO_TRANSLATE} ${TS_FILES})
else()
qt5_add_translation(
QM_FILES ${TS_FILES})
endif()
add_custom_target(
translations
DEPENDS ${QM_FILES})
set_property(
DIRECTORY
PROPERTY CLEAN_NO_CUSTOM TRUE)
add_executable(
ex-qt-translate WIN32
330
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
