Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
QML Qt / Qml / 5_Богатства QML на службе приложения Qt.doc
Скачиваний:
114
Добавлен:
28.03.2016
Размер:
760.83 Кб
Скачать

Создаем виджет

Переходим теперь ко второй части нашей работы – превращению модуля QML в виджет Qt. С основными операциями, которые необходимы для этого, мы познакомились в прошлый раз. Но и теперь нам есть что добавить.дставителем виджета QML в нашей программе Qt является класс Dial (файлы Dial.h, Dial.cpp). Здесь я приведу только объявление класса, остальное вы найдете на диске.

class Dial : public QObject {

Q_OBJECT

Q_PROPERTY(int angle READ angle WRITE setAngle NOTIFY angleChanged)

public:

Dial();

int angle();

void setAngle(int a);

signals: void angleChanged();

private: int m_angle;

};

Тем, кто читал предыдущую стТем, кто читал предыдущую статью и знает Qt, тут все должно быть понятно. Класс экспортирует единственное свойство angle. Напомню только, что метод setAngle() должен явным образом эмитировать сигнал angleChanged(), иначе виджет QML никогда не узнает, что угол изменился. Знатоки сигналов и слотов Qt могут спросить, почему в сигнале angleChanged() не передается новое значение угла поворота. Если бы сигнал предназначался для других классов Qt, я бы так и сделал, но сигнал предназначен для виджета QML, а соответствующий объект этого виджета все равно прочитает значение свойства angle с помощью метода angle() (указанного после ключевого слова READ в макросе Q_PROPERTY). Так что передавать какой-либо параметр в сигнале Qt просто нет необходимости.

Виджет в окне программы

Создание виджета в окне Qt тоже не представляет собой ничего особенно нового, за исключением одного момента, о котором будет сказано ниже. Вот как мы создаем виджет (это фрагмент файла dialcontrol.cpp):

QDeclarativeView *qmlView = new QDeclarativeView;

dial = new Dial();

qmlView->rootContext()->setContextProperty("Dial", dial);

qmlView->setSource(QUrl("qrc:/Dial/Dial.qml"));

QVBoxLayout *layout = new QVBoxLayout(this);

layout->addWidget(qmlView);

Вы, наверное, сразу обратили внимание на то, какую ссылку мы используем для загрузки исходного текста модуля QML. В прошлый раз мы использовали ссылку на файл Linux. Это давало нам огромную свободу в плане модификации внешнего вида окна нашей программы, но делало ее зависимой от расположения файлов QML. Теперь мы поступаем иначе и включаем файл Dial.qml и все сопутствующие ему файлы в модуль ресурсов Qt.

В результате описание виджета QML станет частью программы Qt и нам уже не придется беспокоиться о том, где хранятся соответствующие файлы. Обычно в модули ресурсов включают пиктограммы и элементы интернационализации приложения, но ничто не мешает нам включить в них модули QML, тем более что движок Qt QML умеет работать с пространством ресурсов приложения (и с другими пространствами URL) как с локальной файловой системой. Так что если включенному в модуль ресурсов модулю QML понадобится файл, тоже включенный в модуль ресурсов, модуль QML сможет без проблем загрузить его. Главное, чтобы ссылки на файлы были относительными, а не абсолютными.

Для того чтобы превратить модуль QML в ресурс программы Qt, нам понадобится файл описания ресурсов *.qrc. Работать с файлами с расширением qrc можно многими способами – с помощью дизайнера графических интерфейсов Qt или с помощью программы Qt Creator, но можно обойтись и текстовым редактором, ведь формат qrc основан на XML. Вот как, например, выглядит файл qrc для нашей программы (файл dialcontrol.qrc):

Dial/background.png

Dial/Dial.qml

Dial/DialControl.qrc

Dial/needle.png

Dial/needle_shadow.png

Dial/overlay.png

Внутри тега мы просто указываем путь к файлу ресурса относительно расположения файла qrc. Теперь при сборке приложения виджет QML будет включен в нашу программу. В результате наша программа больше не зависит от расположения файлов QML, но хорошо это или плохо?

С одной стороны, это упрощает установку программы: вам не нужно думать о том, где должны быть размещены файлы QML в соответствии со стандартом XDG, и если вы пишете кросс-платформенное приложение ваша жизнь упрощается еще больше. С другой стороны, при таком подходе теряется одно из важнейших преимуществ QML как средства описания интерфейсов программ Qt: возможность радикально сменить интерфейс без повторной сборки приложения.

Существует еще, своего рода, компромиссный вариант: скомпилировать виджет QML как внешний бинарный ресурс программы Qt (для этого служит утилита rcc). С одной стороны – работать с внешним файлом ресурса в программе Qt не намного сложнее, чем со встроенным, с другой стороны внешний файл ресурса может быть заменен без повторной сборки программы. Однако и у этого подхода есть свой минус: дизайнеру интерфейсов придется иметь дело со специальными инструментами Qt, такими как rcc, тогда как в случае расположения виджета QML целиком в собственных файлах дизайнеру для изменения интерфейса будет достаточно текстового редактора и редактора GIMP (или, на худой конец, Photoshop ;). В общем, наиболее разумный выбор зависит от конкретных целей - хотите ли вы, чтобы каждый пользователь, освоивший QML и растровую графику, мог «сшить новую одежку» для вашей программы, или нет.