Qt Quick - набор технологий для создания пользовательского интерфейса.
Подход основан на использовании описательного языка QML (Qt Meta-object Language). Принцип схож с форматом JSON.
В QML встроен интерпретатор JavaScript, поэтому легко принимает вставки данного языка.
QML содержит множество модулей, как общих для QT так и своих, подключаемых директивой import.
Объекты в QML располагаются древовидной структурой.
Объекты содержат свойства в формате ключ: значение, доступ к объекту можно получить через идентификатор id, к родителю можно обращаться через parent.
В среде Qt Creator вроде как можно работать с QML интерактивно.
Java интерпретируется и применяется сходу, например тут- «width: parent.width / 5», значение сначала высчитывается, на java, после этого присваивается свойству.
Можно вставлять целые функции:
Rectangle { function maximum(a, b) { return a > b ? a:b; } width: maximum(parent.width, 100) }
Функции можно импортировать из внешних файлов
import "myfile.js" as MyScripts (...) Rectangle { width: MyScripts.maximum(parent.width, 100) }
Есть ряд полезных функций для отладки:
console.count() | Кол-во вызова кода |
console.[debug(); log(); info(); error(); warn()]; print() | Вывод сообщений |
console.[time(); timeEnd()] | Замер времени |
console.trace() | Цепочка вызовов java не более 10 |
import QtQuick 2.12 import QtQuick.Window 2.12 Window { width: 640 height: 480 visible: true title: "Hello World" MouseArea { anchors.fill: parent onClicked: console.log('Clicked on background. Text: "'+ textEdit.text +'"') } TextEdit { id: textEdit text: "Enter your text123.." verticalAlignment: Text.AlignVCenter anchors.top: parent.top anchors.horizontalCenter: parent.horizontalLeft anchors.topMargin: 15 Rectangle { anchors.fill: parent anchors.margins: -10 color: "transparent" border.width: 1 } } }
Column; Row; Grid, Flow, Positioner; etc | Для размещения элементов |
Timer; Loader; Connections, WorkerScript; Binding; etc | Инструменты |
[Property; Number; Color; Parallel]Animation; etc | Анимация |
[List; Xml; VisualData; VusialItem]Model; ListElement; etc | Модели |
[Mouse; Drop; Pinch; MultiPointTouch]Area; [Mouse; Key]Event; etc | Пользовательский ввод |
Item | Базовый тип для всех элементов, может выступать в роли окна приложения |
Rectangle | Заполненная прямоугольная область, мб с контуром |
Image (BorderImage) | Растровое изображения (с контуром) |
Text | Форматированный текст |
TextEdit (TextInput) | Ввод и отображение текста |
Window | Элемент главного окна приложения |
WebView | Отображение веб содержания |
Отдельная подгруппа представлений для размещения элементов: ListView, GridView, PathView;
Элементы-потомки отображаются относительно и внутри своего родительского элемента.
import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 360 height: 360 Rectangle { color: "darkkhaki" x: 100 y: 50 width: 170 height: 200 border.color: "black" border.width: 10 radius: 40 smooth: true Text { x: 50 y: 50 text: "Hi, this is string of my text" } } }
Стандартные свойства для всех элементов:
x; y; z; position | Позиционирование |
width; height; implicit[Width; Height] | Задание/получение размеров |
rotation; scale; clip; transform; smooth; transformOrigin; etc | Графические операции и преобразования |
anchors | Фиксация |
id; parent | Ссылки на элементы |
enabled; focus | Доступность; Фокус |
visible; opacity; visibleChildren | Видимость |
states; state; transitions | Состояние и переход |
layer | Работа со слоями |
children; childrenRect | Дочерние элементы |
onWidthChanged; onHeightChanged; etc | Методы, вызываемые при изменении свойств, в них можно размещать код |
import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true width: 360 height: 360 Rectangle { id: redrect color: "red" x: 0 y: 0 width: parent.width / 2 height: parent.height / 2 } Rectangle { color: "green" x: redrect.width y: redrect.height width: redrect.width height: redrect.height } }
property <тип> <имя>[:значение]
Элементам можно задавать собственные свойства. Они могут содержать значения, а так же для них создаются методы onX для реагирования на изменения этих свойств.
Необходимо указывать типы данных, они строго типизированы (bool, double, enumeration, int, list, real, string, time, url, var, color, date, font, matrix4x4, point, rect, size, Vercor[2,3,4]d).
Определяются в отдельных файлах, один файл - один элемент. Используются так же как и стандартные.
Элементы расположенные в одном каталоге автоматически доступны друг для друга.
Из вне будут доступны только свойства базового элемента, но не св-ва вложенных, для этого можно переопределить определить их алиасом в базовом элементе.
// Описание элемента в отдельном файле, в папке в проектом import QtQuick 2.8 Rectangle { property alias text: txt.text property string name: "TextFielddd" width: txt.width height: txt.height Text { id: txt x: 0 y: 0 } }
// Использование элемента import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true; width: 360; height: 360 TextField { x: 10 y: 20 color: "yellow" text: "This Text in myTextField<br>Second String" border.width: 1 } }
Коллекции QML элементов можно объединять в модули и использовать повторно, подключив директивой import.
Располагают их в отдельной папке, создают файл qmldir с картой описания qml файлов элементов, с указанием версии.
Элемент Repeater позволяет производить элементы используя любой тип модели данных (число, массив, набор JSON), это инструкция к созданию, а элемент внутри, является шаблоном.
import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true; width: 360; height: 360 Repeater { model: ["one", "two", "three", "four"] Text { text: modelData // обращение к массиву значений y: index * 20 // index - номер текущего элемента } } }
Flickable - типа скроллбара, в нем можно располагать элементы большого размера
В модуле QtQuick.Controls содержится ряд готовых элементов GUI.
Такие элементы как: CheckBox, DelayButton, RadioButton, PoundButton, Switch, ToolButton, Button, BusyIndicator, ComboBox, Dial, Label, PageIndicator, ProgressBar, RangeSlider, Slider, SpinButton, ToolBar, Tumbler.
Область основного окна делится на три зоны: Верхняя (header), Нижняя (footer) и Рабочая (в середине)
import QtQuick 2.8 import QtQuick.Window 2.2 Window { visible: true; width: 360; height: 360 header: ToolBar { //AnyElements } footer: ToolBar { //AnyElements } //AnyElements in Center }
Так же, в модуле QtQuick.Extras есть аналогичные, но выглядящие более специфично, элементы.
В основном это: FileDialog, FontDialog, ColorDialog и MessageDialog.
import QtQuick 2.8 //import QtQuick.Window 2.2 import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 ApplicationWindow // Window { visible: true; width: 200; height: 150 Repeater { id: repeater model: [colorDialog, fontDialog, fileDialog] Button { y: index * (parent.height / repeater.count) height: parent.height / repeater.count width: parent.width text: modelData.title onClicked: { messageDialog.visible = false modelData.visible = true } } } ColorDialog { id: colorDialog visible: false modality: Qt.WindowModal title: "Select color" color: "blue" onAccepted: { messageDialog.informativeText = "Selected color: "+ color messageDialog.visible = true } } FontDialog { id: fontDialog visible: false modality: Qt.WindowModal title: "Select font" onAccepted: { messageDialog.informativeText = "Selected font: "+ font messageDialog.visible = true } } FileDialog { id: fileDialog visible: false modality: Qt.WindowModal title: "Select file" folder: "C:\\Users\\" nameFilters: ["All files (*)"] onAccepted: { messageDialog.informativeText = "Selected file: "+ fileUrls messageDialog.visible = true } } MessageDialog { id: messageDialog visible: false modality: Qt.NonModal title: "Message" } }
Фиксатор (anchors) позволяет определить расположение одного элемента относительно других.
В QML все элементы вложены друг в друга и располагаются элементы относительно своего родителя.
Для фиксации можно использовать свойства: left, right, top, bottom, {horizontal,vertical}Center
import QtQuick 2.12; import QtQuick.Window 2.12 Window { width: 640; height: 480; visible: true; Rectangle { anchors.fill: parent Text { text: "This is text in text-element" anchors.centerIn: parent // или аналогично: //anchors.horizontalCenter: parent.horizontalCenter //anchors.verticalCenter: parent.verticalCenter } } }
Эти же свойства можно использовать для заполнения элементом области
import QtQuick 2.12; import QtQuick.Window 2.12 Window { width: 640; height: 480; visible: true; Rectangle { // Для группы свойств anchors { left: parent.left right: parent.right top: parent.top bottom: parent.bottom } // Аналогично //anchors.fill: parent } }
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 640; height: 480; visible: true; Rectangle { anchors.fill: parent Rectangle { id: firstRec color: "red" width: parent.width / 1.5 height: parent.height / 1.5 anchors.left: parent.left anchors.top: parent.top } Rectangle { opacity: 0.5 color: "blue" anchors { top: firstRec.verticalCenter left: firstRec.horizontalCenter right: parent.right bottom: parent.bottom } } } }
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 640; height: 480; visible: true; Rectangle { anchors.fill: parent Rectangle { id: leftrec width: 60 color: "blue" anchors { left: parent.left top: parent.top bottom: parent.bottom topMargin: 10 bottomMargin: 10 } } Rectangle { id: rightrec width: 60 color: "blue" anchors { right: parent.right top: parent.top bottom: parent.bottom topMargin: 10 bottomMargin: 10 } } Rectangle { id: centerrec color: "green" anchors { top: parent.top bottom: parent.bottom left: leftrec.right right: rightrec.left } } } }
Размещения являются элементами
Row, RowLayout | Горизонтальное размещение, аналог QHBoxLayout |
Column, ColumnLayout | Вертикальное размещение, аналог QVBoxLayout |
Grid, GridLayout | Табличное размещение, аналог QGridLayout |
StackLayout | Одновременно можно видеть только один элемент, аналог QStackLayout |
Содержат свойства spacing и layoutDirection, для установки промежутков и управления направлением размещения.
Элементы со словом layout, содержатся в модуле QtQuick.Layouts и обладают доп. свойством Layout:
.minimum{Width,Heigth} | минимальная ширина/высота |
.maximum{Width,Heigth} | максимальная ширина/высота |
.preferred{Width,Heigth} | предпочтительная ширина/высота |
.fill{Width,Heigth} | заполнение по ширине/высоте элемента |
import QtQuick 2.12; //import QtQuick.Window 2.12 import QtQuick.Controls 2.2 ApplicationWindow { width: 640; height: 480; visible: true; Rectangle { anchors.fill: parent Row { anchors.centerIn: parent spacing: 10 Rectangle { width: 64; height: 64; color: "red" } Rectangle { width: 64; height: 64; color: "yellow" } Rectangle { width: 64; height: 64; color: "green" } } } }
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: 640; height: 480; visible: true; Rectangle { anchors.fill: parent RowLayout { anchors.fill: parent spacing: 10 Layout.margins: 10 Rectangle { Layout.minimumWidth: 64; Layout.minimumHeight: 64; color: "red"; Layout.fillHeight: true } Rectangle { Layout.minimumWidth: 64; Layout.minimumHeight: 64; color: "yellow"; Layout.fillWidth: true } Rectangle { Layout.minimumWidth: 64; Layout.minimumHeight: 64; color: "green"; Layout.fillHeight: true } } } }
Упорядочивает элементы змейкой, пытаясь уместить их как можно больше.
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: 640; height: 480; visible: true; Rectangle { anchors.fill: parent Flow { anchors.fill: parent anchors.margins: 20 spacing: 20 Repeater { model: { var v = new Array(10); for(var i= 0; i < v.length; ++i) v[i]= i % 2 ? "green" : "red" return v; } Rectangle { width: 64; height: 64; radius: 32; color: modelData Text { color: "white"; font.pixelSize: 48; font.family: "Courier"; anchors.centerIn: parent; text: index } } } } } }