Перейти к содержимому

Qtquick что это

  • автор:

Qt Quick (Qt User Interface Creation Kit)

Ключевой особенностью Qt 4.7 и Qt Creator 2.1 является Qt Quick: высокоуровневая UI технология, которая позволяет разработчикам и дизайнерам работать вместе над одним проектом и создавать красивые, анимированные программы. Qt Quick включает:

  1. QML дизайнер для Qt Creator IDE
  2. QML (Qt Meta-Object Language): легко используемый, декларативный язык
  3. QtDeclarative: новый модуль, предоставляющий декларативный подход для разработки динамичных пользовательских интерфейсов

Для работы с QML нет необходимости быть разработчиком. Описать интерфейс и его поведение очень просто не имея навыков программирования на C+. Но при необходимости элементы дизайна можно расширить с помощью C+.

Scope (Qt Creator 2.1 и Quick)

  • Мастер создания и менеджер QML проектов. (новый формат файла для приложений на чистом QML)
  • Расширенный редактор QML с подсветкой синтаксиса, автодополнением кода, встроенной справкой и др.
  • Qt Quick Designer: WYSIWYG редактор для создания Qt Quick пользовательских интерфейсов (technical preview)
  • Qt Quick Components: Основные UI элементы, которые соответствуют идее Look & Feel

Введение в компоненты управления Qt Quick Controls

Использование Qt Quick с нуля дает вам примитивные графические и интерактивные элементы, из которых вы можете создавать свои пользовательские интерфейсы. Используя Qt Quick Controls, вы начинаете с немного более структурированного набора элементов управления, из которых можно строить пользовательский интерфейс.

Эти элементы управления включают в себя от простых текстовых меток и кнопок до более сложных, таких как ползунки и циферблаты. Эти элементы удобны, если вы хотите создать пользовательский интерфейс на основе классических шаблонов взаимодействия, поскольку они обеспечивают хорошую основу, на которую можно опереться.

Компоненты Qt Quick Controls поставляются с набором стилей, которые показаны ниже. Стиль Basic – это базовый плоский стиль. Стиль Universal основан на Универсальных рекомендациях по дизайну Microsoft, в то время как Material основан на Руководствах по материальному дизайну Google, а стиль Fusion – это стиль, ориентированный на десктопные приложения.

Некоторые стили можно настроить, изменив палитры. Стиль Imagine основан на ресурсах изображений, что позволяет графическому дизайнеру создавать новый стиль вообще без написания кода, даже для цветовых кодов палитры.

  • Basic Basic
  • Fusion Fusion
  • macOS macOS
  • Material Material
  • Imagine Imagine
  • Windows Windows
  • Universal Universal

Qt Quick Controls 2 доступен из импорта QtQuick.Controls . Также представляют интерес следующие модули:

  • QtQuick.Controls – основные элементы управления.
  • QtQuick.Templates – предоставляет поведенческие, невизуальные базовые типы для элементов управления.
  • QtQuick.Controls.Imagine – поддержка тем в стиле Imagine.
  • QtQuick.Controls.Material – поддержка тем в стиле Material.
  • QtQuick.Controls.Universal – поддержка тем в стиле Universal.
  • Qt.labs.platform – поддержка собственных диалогов платформы для распространенных задач, таких как выбор файлов, цветов и т.д., а также значков на панели задач и стандартных путей.

Qt.Labs

Обратите внимание, что модули Qt.labs являются экспериментальными, а это означает, что их API могут иметь критические изменения между версиями Qt.

QML Самоучитель

Уже давно вышла версия Qt4 c поддержкой QML. С тех пор многое допиливалось и сейчас технология является довольно успешной и стабильной. Однако нормального описания так и не удавалось найти на русском языке. А на английском написано так, как говорится, «правой рукой, да левое ухо». Поэтому решил начать перевод самоучителя (пока базового, затем планирую расширенный) на русский язык. Собственно, найти самоучитель можно на моем GitHub или здесь ниже.

QML Самоучитель

В данном руководстве содержится введение в QML (язык интерфейсов Qt Quick). Оно охватывает не все — акцент делается на обучении базовым принципам, а особенности и дополнения приводится по мере необходимости.

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

Первая глава начинается с минимальной программы «Привет, мир», в следующих же главах приведены новые концепции.

Исходные коды из руководства находится в Qt каталоге:

examples/quick/tutorials/helloworld

Главы руководства:

  1. Базовые Типы.
  2. Компоненты QML.
  3. Состояния и переходы.

Глава 1 — Базовые Типы

Первая программа представляет собой очень простой «Hello world» пример, который познакомит вас с некоторыми базовыми концепциями QML.

На рисунке ниже показан скриншот этой программы:

QML код приложения:

import QtQuick 2.0 Rectangle < id: page width: 320; height: 480 color: "lightgray" Text < id: helloText text: "Hello world!" y: 30 anchors.horizontalCenter: page.horizontalCenter font.pointSize: 24; font.bold: true >>

Разбор по шагам

Импорт

Сперва нужно импортировать типы, которые нужны вам для этого примера. Большинство файлов QML импортируют встроенные типы QML (например, Rectangle, Image, . ), которые поставляются с Qt, используя:

import QtQuick 2.0
Тип — Прямоугольник
Rectangle < id: page width: 320; height: 480 color: "lightgray"

Здесь объявляется корневой объект типа Rectangle (Прямоугольник). Это один из основных строительных блоков, которые вы можете использовать для создания приложения на QML. Далее ему присваивается идентификатор, чтобы была возможность ссылаться на него в дальнейшем. В данном случае идентификатор имеет значение "page". Также устанавливаются свойства ширины, высоты и цвета. Тип Rectangle содержит много других свойств (таких как x и y), но они будут инициированы со значениями по умолчанию.

Тип - Текст
Text

Здесь добавляется тип Text в качестве дочернего элемента корневого типа Rectangle, который отображает текст "Hello world!".

Свойство y используется для позиционирования текста по вертикали на расстоянии 30 пикселей от верхней части его родительского элемента.

Свойство anchors.horizontalCenter прикладывается к горизонтальному центру типа. В этом случае указывается, что тип Text должен быть горизонтально центрирован в элементе "page" (см. Anchor-Based Layout).

Размер font.pointSize и font.bold связаны со шрифтами и используют точечную нотацию.

Просмотр примера

Чтобы просмотреть то, что вы создали, запустите инструмент qml (расположенный в каталоге bin) с вашим именем файла в качестве первого аргумента. Например, чтобы запустить предоставленный пример завершенной Главы 1 из места установки, вы должны ввести:

qml tutorials/helloworld/tutorial1.qml

Глава 2 - Компоненты QML

В этой главе описывается средство для изменения цвета текста.

На скриншоте выше изображен набор цветов, состоящий из шести ячеек с разными цветами. Чтобы избежать повторения одного и того же кода для каждой ячейки, создается новый компонент ячейки (компонент Cell). Компонент предоставляет способ определения нового типа, который можно повторно использовать в других файлах QML. Компонент QML подобен черному ящику и взаимодействует с внешним миром через свойства, сигналы и функции и обычно определяется в его собственном файле QML. (см. Документацию по Component). Имя файла компонента всегда должно начинаться с заглавной буквы английского алфавита.

Ниже показан QML код для Cell.qml:

import QtQuick 2.0 Item < id: container property alias cellColor: rectangle.color signal clicked(cellColor: color) width: 40; height: 25 Rectangle < id: rectangle border.color: "white" anchors.fill: parent >MouseArea < anchors.fill: parent onClicked: container.clicked(container.cellColor) >>

Разбор по шагам

Cell компонент
Item < id: container property alias cellColor: rectangle.color signal clicked(cellColor: color) width: 40; height: 25

Корневой тип нашего компонента - это элемент (Item) с идентификатором (ID) равным container. Элемент (Item) является самым основным визуальным типом в QML и часто используется в качестве контейнера для других типов.

property alias cellColor: rectangle.color

Выше объявляется свойство cellColor (цвет ячейки). Данное свойство доступно извне компонента, это позволяет создавать экземпляры ячеек с разными цветами. Это свойство является просто псевдонимом существующего свойства - цвета прямоугольника, составляющего ячейку (см. Привязку свойства).

signal clicked(cellColor: color)

Также нужно, чтобы у нашего компонента был сигнал, который мы вызываем при нажатии (clicked) с параметром цвета ячейки типа цвета (color). Позже мы будем использовать данный сигнал для изменения цвета текста в основном файле QML.

Rectangle

Компонент ячейки в основном представляет собой цветной прямоугольник с идентификатором (ID) rectangle.

Свойство anchors.fill - это удобный способ задать размер визуального типа. В этом случае прямоугольник будет иметь тот же размер, что и его родительский (parent) элемент (см. Макет на основе привязки).

MouseArea

Чтобы изменить цвет текста при щелчке по ячейке, создается тип MouseArea (область мышки) с тем же размером, что и ее родительский элемент.

Основной файл QML

В основном файле QML используется ранее созданный компонент Cell для создания средства выбора цвета:

import QtQuick 2.0 Rectangle < id: page width: 320; height: 480 color: "lightgray" Text < id: helloText text: "Hello world!" y: 30 anchors.horizontalCenter: page.horizontalCenter font.pointSize: 24; font.bold: true >Grid < id: colorPicker x: 4; anchors.bottom: page.bottom; anchors.bottomMargin: 4 rows: 2; columns: 3; spacing: 3 Cell < cellColor: "red"; onClicked: helloText.color = cellColor >Cell < cellColor: "green"; onClicked: helloText.color = cellColor >Cell < cellColor: "blue"; onClicked: helloText.color = cellColor >Cell < cellColor: "yellow"; onClicked: helloText.color = cellColor >Cell < cellColor: "steelblue"; onClicked: helloText.color = cellColor >Cell < cellColor: "black"; onClicked: helloText.color = cellColor >> >

Создается средство выбора цвета, представляя собой сетку из 6 ячеек с разными цветами.

Когда срабатывает сигнал щелчка мыши (clicked signal) по ячейке, установится цвет текста равным цвету ячейки, переданному в качестве параметра cellColor. Можно реагировать на любой сигнал нашему компоненту с помощью свойства с именем 'onSignalName' (см. Атрибуты сигнала).

Глава 3 - Состояния и переходы

В данной главе предыдущий пример станет немного более динамичным, используя состояния и переходы.

Нужно, чтобы текст перемещался в нижнюю часть экрана, поворачивался и становился красным при нажатии.

Ниже приведен QML код:

import QtQuick 2.0 Rectangle < id: page width: 320; height: 480 color: "lightgray" Text < id: helloText text: "Hello world!" y: 30 anchors.horizontalCenter: page.horizontalCenter font.pointSize: 24; font.bold: true MouseArea < id: mouseArea; anchors.fill: parent >states: State < name: "down"; when: mouseArea.pressed == true PropertyChanges < helloText < y: 160 rotation: 180 color: "red" >> > transitions: Transition < from: ""; to: "down"; reversible: true ParallelAnimation < NumberAnimation < properties: "y,rotation"; duration: 500; easing.type: Easing.InOutQuad >ColorAnimation < duration: 500 >> > > Grid < id: colorPicker x: 4; anchors.bottom: page.bottom; anchors.bottomMargin: 4 rows: 2; columns: 3; spacing: 3 Cell < cellColor: "red"; onClicked: helloText.color = cellColor >Cell < cellColor: "green"; onClicked: helloText.color = cellColor >Cell < cellColor: "blue"; onClicked: helloText.color = cellColor >Cell < cellColor: "yellow"; onClicked: helloText.color = cellColor >Cell < cellColor: "steelblue"; onClicked: helloText.color = cellColor >Cell < cellColor: "black"; onClicked: helloText.color = cellColor >> >

Разбор по шагам

states: State < name: "down"; when: mouseArea.pressed == true PropertyChanges < helloText < y: 160 rotation: 180 color: "red" >> >

Сначала создается новое состояние down для текстового типа. Это состояние будет активироваться при нажатии кнопки мышки и деактивироваться при ее отпускании.

Состояние down включает в себя набор изменений свойств из неявного дефолтного (default) состояния (элементы в том виде, в каком они были изначально определены в QML). В ручную (специально) устанавливаются свойства текста равными: положение по вертикали (y) равное 160, поворот - 180 и цвет - красный.

transitions: Transition < from: ""; to: "down"; reversible: true ParallelAnimation < NumberAnimation < properties: "y,rotation"; duration: 500; easing.type: Easing.InOutQuad >ColorAnimation < duration: 500 >> >

Чтобы текст появлялся внизу не мгновенно, а перемещался плавно - добавляется переход между нашими двумя состояниями.

"from" и "to" определяют состояния, между которыми будет выполняться переход. В этом случае происходит переход из состояния по умолчанию в состояние down.

Поскольку требуется, чтобы тот же переход выполнялся в обратном порядке при возврате из состояния down в дефолтное состояние, мы устанавливаем значение reversable равным true. Это эквивалентно записи двух переходов по отдельности.

Тип ParallelAnimation гарантирует, что два типа анимации (число и цвет) запускаются одновременно (параллельно). Также возможно бы запускать их один за другим, используя вместо этого SequentialAnimation.

Дополнительные сведения о состояниях и переходах см. в разделе Состояния QtQuick, а также Пример реализации состояний и переходов.

Послесловие

Данный туториал-самоучитель решил выложить здесь, т.к. GitHub стал блокировать репозитории русских компаний и, кто знает, может начнет и обычных людей банить. А Habr - наш, родненький.

Второй момент - автор данного перевода (то есть я) не является профессиональным переводчиком, поэтому ошибки могут присутствовать. Спасибо за понимание.

И на последок, не могу не сказать, что оригинальный туториал можно найти на официальном сайте Qt. Все, права защищены и бла-бла-бла.

© 2022 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.

Qt + QML на простом примере

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

Это будет минималистичное приложение, cмысл его простой — при нажатии на любую клавишу на клавиатуре на экране будет появляться случайное изображение и будет проигрываться, опять же, случайный звуковой эффект.

Пользовательский интерфейс будет полностью реализован на QML, программная часть на Qt.

Для тех, у кого Qt еще не установлен, заходим на страницу загрузки qt.nokia.com/downloads и в разделе "Qt SDK: Complete Development Environment" скачиваем бинарники для своей платформы. И, собственно, устанавливаем.

Запускаем Qt Creator, выбираем пункт меню Файл -> Новый файл или проект. В открывшемся окне Проект Qt C++ -> Gui приложение Qt, далее кнопка Выбрать.

Qt

В новом окне вводим название проекта, указываем путь к проекту, жмем Далее.

В следующем окне снимаем галочку Создать форму, она нам не пригодиться, Далее. И в последнем просто нажимаем кнопку Завершить. Все, каркас нашего приложения создан.

Qt

Первым делом добавим модуль qt-declarative к нашему проекту, для этого, в файле проекта (4Toddler.pro), к строке

QT += core gui

добавим declarative

QT += core gui declarative

Далее изменим базовый класс для нашего главного окна, заменим QMainWindow на QDeclarativeView и включим заголовочный файл QDeclarativeView

class MainWindow : public QDeclarativeView
.
>

От реализации конструктора отрежем, ставшую ненужной, инициализацию базового класса QMainWindow(parent).

Если сейчас собрать и запустить проект то мы увидим пустое окно. Так и должно быть, т.к. мы еще не создали и не инициализировали Qml интерфейс.

Добавим в проект новый QML файл, для этого щелкаем правой клавишей по проекту

image

Добавить новый. , далее выбираем раздел Qt, шаблон Файл Qt QML. Даем ему имя main, затем Далее и Завершить.

image

Мастер создал нам файл, содержащий один элемент Rectangle, он и будет являться основным элементом для нашего пользовательского интерфейса. Добавим несколько новых свойств и зададим их значение

Rectangle
// Идентификатор, по нему будет происходить
// обращение к свойствам этого элемента
id: canvas;

// Цвет фона, черный
color: "black"

// Изменять размер под размеры
// родительского элемента
anchors.fill: parent

// Будет получать фокус ввода
focus: true
>

Пока ничего особенного, просто черный фон. Добавим код загрузки QML файла, чтобы посмотреть, что у нас получилось. Для этого добавим нашему окну новый метод

void MainWindow::Init()
// Путь к папке, содержащей QML файлы
QString contentPath;

#ifdef QT_DEBUG
// В отладочной версии это абсолютный путь к папке проекта
contentPath = "D:/MyProjects/QT/4Toddler" ;
#else
// В релизе это путь к папке, в которой расположено приложение
contentPath = QApplication::applicationDirPath();
#endif

setFocusPolicy(Qt::StrongFocus);
// Изменять размеры QML объекта под размеры окна
// Возможно делать и наоборот,
// передавая QDeclarativeView::SizeViewToRootObject
setResizeMode(QDeclarativeView::SizeRootObjectToView);

// Загрузить QML файл
setSource(QUrl::fromLocalFile(contentPath + "/main.qml" ));
>

Теперь заменим в файле main.cpp строку

int main( int argc, char *argv[])
.
w.show();
.
>

int main( int argc, char *argv[])
.
w.showFullScreen();
.
>

Окно будет разворачиваться на весь экран. Прежде, чем запускать приложение, давайте добавим кнопку, с помощью которой можно будет закрыть окно. Забегая вперед скажу, кнопок в окне будет две, для того, чтобы не писать несоклько раз один и тот же код добавим к проекту новый QML файл, и назовем его WindowButton.

Элемент WindowButton мы будем использовать повторно, изменяя лишь определенные свойства у каждого экземпляра. Кнопки у нас будут выполнены в виде иконок, каждой из них мы будем задавать путь к файлу иконки и изменять обработчик нажатия левой клавишей мыши. Ниже приведен готовый код элемента с комментариями

// Область, обрабатывающая "мышиные" сообщения
MouseArea
// Действует в пределах всего
// элемента Image
anchors.fill: parent

// При нажатии вызвать метод callback
onClicked: callback()
>
>

Добавим пару кнопок к нашему окну

// Элемент позволяющий
// распологать элементы горизонтально
Row
// Правый край элемента выравнивается
// по правому краю родительского элемента
anchors.right: parent.right;
// Отступ справа, 4 пикселя
anchors.rightMargin: 4;
// Верхний край эелемента выравнивается
// по верхнему краю родительского элемента
anchors.top: parent.top;
// Отступ сверху, 4 пикселя
anchors.topMargin: 4;

// Отступ между элементами
spacing: 4

WindowButton
// Кнопка возова диалога "О программе"
id: about;

// Путь к файлу с изображением
// в данном случае иконка лежит в той же папке,
// что и QML файл
source: "about.png" ;

// Метод, который будет вызываться
// при нажатии на кнопку левой клавишей мыши
// onClicked: callback()
function callback()
>
>

WindowButton
// Кнопка закрытия окна
id: exit;

Чтобы то, что мы сделали заработало нам осталось реализовать оба метода callback для каждой кнопки. Для закрытия окна мы вызовем метод Quit, который реализуем в классе окна. Для этого в объявление класс добавим

Q_INVOKABLE void Quit();

Затем реализуем этот метод

void MainWindow::Quit()
QApplication::quit();
>

Осталось сделать этот метод видимым из QML. В метод Init добавим одну единствунную строку, которая сделает экземпляр нашего окна видимым в QML

rootContext()->setContextProperty( "window" , this );

Обращаться к этому объекту мы сможем по имени — window, имя это произвольное. Добавим реализацию для кнопки закрытия окна

function callback()
window.Quit();
>

Обратите внимание, что вызывать можно только те методы, которые объявлены как Q_INVOKABLE, т.е. от же метод Init, главного окна вызвать не удастся.

Готово, запускаем, видим черный экран, все, что сейчас мы можем сделать это закрыть окно, нажав на кнопку exit. Нажали и видим, что состояние кнопки при наведении курсора и при нажатии никак не меняется, выглядит как «неживая». Оживим ее, добавив состояния:

Image
.
states:[
State
// Произвольное название
name: "hovered" ;
// Указание на то, когда элемент переходит в это состояние
// в данном случае когда нажата левая кнопка мыши
when: mouseArea.pressed;
// Какие свойства будут изменяться в этом состоянии
// в данном случае это будет прозрачность
PropertyChanges < target: button; opacity: 1;>
>,
State
name: "normal"
// В это состояние элемент будет переходить
// когда левая кнопка мыши не нажата
when: mouseArea.pressed == false ;
PropertyChanges < target: button; opacity: 0.7; >
>
]
>

Элемент может переходить в определенное состояние как автоматически при выполнении условия, указанного в when, так и вручную, путем изменения свойства state.

Запустили, нажали, прозрачность изменяется, уже лучше, но не хватает плавности. Добавим следующий код:

Image
.
Behavior on opacity
// Анимация с шагом в 100 миллисекунд
// Раз в 100 миллисекунд прозрачность будет изменяться
// на 0,1
NumberAnimation < duration: 100 >
>
>

Behavior очень полезный элемент для создания анимаций, позволяющий указать то как будет меняться указанное свойство, в данном случае прозрачность кнопки.

Запускаем и смотрим, совсем другое дело, плавный переход от полупрозрачного к непрозрачному состоянию.

Окно о программе будет реализовано полностью на QML. Это будет модальное окно, которое будет появляться при нажатии кнопки about. При щелчке левой клавишей мыши в любом месте окна оно будет исчезать. Добавим новый QML файл About.qml в проект.

Я приведу сразу весь код этого окна с пояснениями

// Главный элемент для диалогового окна
Rectangle
id: about

// Функция для отображения окна
// изменяет прозрачность главного элемента
function show()
about.opacity = 1;
>

// Функция для закрытия окна
function hide()
about.opacity = 0;
>

// Прозрачный задний фон
color: "transparent"
// Полностью прозрачен по умолчанию
opacity: 0

// Ширина и высота устанавливаются равными
// ширине и высоте родительского элемента
// в данном случае это элемент с id: canvas
width: parent.width
height: parent.height

// Видимым элемент будет считаться если выполняется условие
// opacity > 0
visible: opacity > 0

// Дочерний элемент, создающий полупрозрачный фон
Rectangle
anchors.fill: parent

// Дочерний элемент создающий который является диалогом
// "О программе. "
Rectangle
id: dialog

// Ширина и высота являются фиксированными
width: 360
height: 230

// Координаты верхнего левого угла вычисляются
// исходя из размеров самого диалога и родителя
// так, чтобы окно располагалось в центре
x: parent.width / 2 - dialog.width / 2;
y: parent.height / 2 - dialog.height / 2;
// Задаем z индекс таким, чтобы он был
// больше z тех элементов, которые должны остаться
// за диалоговым окном
z: 10

Text
text: "4 Toddler"

// Выравнивание элемента по центру
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
>
>

Behavior on opacity
NumberAnimation < duration: 100 >
>

MouseArea
// Элемент полностью заполняет родительский элемент
anchors.fill: parent;

// При клике в любом месте прячем окно
onClicked: hide();
>
>

Для начала хотелось бы обратить внимание на свойство

width: parent.width

Это не просто присвоение ширины, если в процессе отображения будет меняться ширина родительского элемента, то и ширина дочернего будет перерасчитана. Не знаю как вас, а меня в процессе «ковыряния» QML эта особенность приятно удивила. Так же интересна следующая строка:

visible: opacity > 0

Свойство может быть не только задано, но и вычислено.

Осталось добавить диалог и код для его отображения при нажатии кнопки about. В файл Main.qml добавим код, в конце элемента canvas

Rectangle
id: canvas
..
About
id: aboutDlg
>
>

Для того, чтобы окно отображалось добавим строку

aboutDlg.show();

в функцию callback кнопки about

WindowButton
id: about;
.
function callback()
aboutDlg.show();
>
>

Теперь добавим, собственно основной функционал. Начнем с отображения случайной картинки при нажатии любой клавиши. Картинка будет являться эелементом Image, определим этот элемент в отдельном файле. Добавим в проект файл Block.qml

// Новое свойство объекта, необходимое
// для изменения состояния при удалении объекта
property bool remove: false
// При добавлении объекта
property bool show: false

opacity: 0;
fillMode: Image.Stretch;

states: [
State
// Состояние, в которое переходит объект
// тогда, когда нам нужно его удалить
name: "remove" ; when: remove == true ;
PropertyChanges < target: block; opacity: 0 >
StateChangeScript < script: block.destroy(1000); >
>,
State
// Состояние, в которое переходит объект
// тогда, когда нам нужно его отобразить
name: "show" ; when: show == true ;
PropertyChanges < target: block; opacity: 1 >
>
]

При нажатии любой клавиши на клавиатуре будет отображаться блок с произвольной картинкой. Добавим в проект новый файл main.js. В нем, мы определим обработчик нажатия клавиши на клавиатуре.

// Шаблон для создания новых элементов
var component = Qt.createComponent( "block.qml" );

// Максимальное количество элементов
var maxBlocksCount = 10;

// Массив, в котором будут храниться все эелементы
var blocksArray = new Array();

// Функция обработчик нажатия клавиши
function handleKey()
// Координата x - случайно число от 0 до ширины окна
var x = Math .floor( Math .random() * canvas.width);
// Координата y - случайно число от 0 до ширины окна
var y = Math .floor( Math .random() * canvas.height);

// Вызов функции, которая создаст новый элемент
// с указанными координатами
createNewBlock(x, y);
>

// Создание нового элемента
function createNewBlock(x, y)
if (component.status != Component.Ready)
return false ;
>

// Удалить лишние элементы
if (blocksArray.length > maxBlocksCount)
removeAllBlocks();
>

var newBlock = component.createObject(canvas);

if (newBlock == null )
return false ;
>

// Путь к файлу иконки доступен через свойство главного
// окна randomIcon
var iconFile = window.randomIcon;

newBlock.source = ( "Icons/" + iconFile);

newBlock.x = x;
newBlock.y = y;

// Переводим элемент в состояние show
newBlock.show = true ;

// Проигрываем случайный звуковой эффект
window.PlaySound();

// Удаление всех добавленных элементов
function removeAllBlocks()
for ( var i = 0; i < blocksArray.length; ++i)
blocksArray[i].remove = true ;
>

Как видно из кода нам еще следует реализовать свойство randomIcon и функицию PlaySound главного окна.

Добавим свойство в объявление класса MainWindow

Q_PROPERTY(QString randomIcon READ RandomIcon)

И объявление функции

QString RandomIcon();

QString MainWindow::RandomIcon()
QStringList iconFilesList;
QString searchPath = m_ContentPath + "/Icons/" ;

QDir directory = QDir(searchPath);
QStringList filters;
filters directory.setNameFilters(filters);
// Получаем список файлов с расширением png
iconFilesList = directory.entryList(QDir::AllEntries);

// Получаем случайный индекс элемента
int fileIdx = qrand() % iconFilesList.count();

// Возвращаем название файла
return iconFilesList.at(fileIdx);
>

Теперь добавим в заголовочный файл функцию для проигрывания звукового эффекта

Q_INVOKABLE void PlaySound();

и реализацию

void MainWindow::PlaySound()
QStringList soundFilesList;
QDir directory = QDir(m_ContentPath + "/Sounds/" );
QStringList filters;
filters directory.setNameFilters(filters);

// Получаем список файлов с расширением wav
soundFilesList = directory.entryList(QDir::AllEntries);
// Получаем случайный индекс элемента
int fileIdx = qrand() % soundFilesList.count();

// Получаем название файла
QString soundFile = m_ContentPath + "/Sounds/" + soundFilesList.at(fileIdx);
// Проигрываем файл
QSound::play(soundFile);
>

Почти все, осталось добавить обработчик нажатия клавиш в наш корневой элемент вызов фунции создания нового элемента. В начален файла main.qml сделаем видимым наш скрипт в файле main.qml

import Qt 4.7
import "main.js" as Main

и сам обработчик внутри элемента canvas

Rectangle
id: canvas
.
Keys.onPressed: < if ( event .isAutoRepeat == false ) < Main.handleKey(); >>

На этом все — можем запускать и любоваться.

Как я и обещал программа является простой, но, на мой взгляд, это достаточно интересная «игровая» площадка для тех, кто только начинает изучать QML. Нет предела совершенству, кто знает, может кто-нибудь разовьет ее во что-то более стоящее.

Архив с проектом можно скачать здесь

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *