Это старая версия документа!
Можно использовать форматы: JPG, PNG и SVG.
Этот элемент отображает файл изображения, указанный в свойстве source, файл может находится как локально так и в сети.
Есть интерактивный редактор для изменения свойств.
Свойствами можно подвергать изображение трансформациям, типа увеличение/уменьшение (scale), поворот (rotation), сглаживание (smooth).
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: img.width; height: img.height; visible: true; Rectangle { anchors.fill: parent Image { id: img source: "qrc:/../../../../Downloads/11.jpg" x: 0; y: 0 smooth: true scale: 0.75 rotation: -30 } } }
Для более тонкой настройки трансформации, ее можно задавать списками (в квадратных скобках).
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: img.width; height: img.height; visible: true; Rectangle { anchors.fill: parent Image { id: img source: "qrc:/../../../../Downloads/11.jpg" x: 0; y: 0 smooth: true transform: [ Scale { origin.x: width / 2 origin.y: width / 2 xScale: 0.75 yScale: 0.75 }, Rotation { origin.x: width / 2 origin.y: width / 2 angle: -30.0 } ] } } }
Добавим элемент загрузки BusyIndicator
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 Image { id: img source: "http://qt-book.com/pic.jpg" anchors.fill: parent smooth: true Column { anchors.centerIn: parent visible: img.status == Image.Loading ? true:false Text { text: "Загрузка..." } BusyIndicator {} } } } }
Элемент для нормального масштабирования графики, особенно полезно при закругленных углах (кнопок и т.д.). Элемент разбивает изображение на девять частей.
import QtQuick 2.12 BorderImage { source: "" width: 100; height: 45 border {left: 30; top: 15; right: 30; bottom: 15} }
В QML есть только один градиент - линейный, если нужен другой, можно воспользоваться трансформацией.
Для создания, нужно свойству gradient присвоить элемент Gradient, он содержит точки останова (GradientStop) с позициями от 0 до 1.
Создание градиентов может потребовать много ресурсов, поэтому эффективнее использовать изображение градиента.
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 gradient: Gradient { GradientStop{position: 0.0; color: "blue"} GradientStop{position: 0.7; color: "gold"} GradientStop{position: 1.0; color: "silver"} } rotation: 30 scale: 1.5 } }
Canvas представляет собой элемент холста, на котором можно выполнять растровые операции, по сути аналогичен QPaintDevice.
Сам QML описательный язык, поэтому алгоритмы рисования реализуются с использованием JavaScript, в свойстве обработки onPaint.
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: 480; height: 480; visible: true; Rectangle { anchors.fill: parent Canvas { anchors.fill: parent; onPaint: { function drawFantasy() { ctx.beginPath(); ctx.translate(parent.width / 2, parent.height / 2); var fAngle = 91 * 3.14156 / 180 for(var i = 0; i < 300; ++i) { var n = i * 2; ctx.moveTo(0, 0); ctx.lineTo(n, 0); ctx.translate(n, 0); ctx.rotate(fAngle) } ctx.closePath(); } var ctx = getContext("2d"); ctx.clearRect(0, 0, parent.width, parent.height); ctx.save(); ctx.strokeStyle = "black"; ctx.lineWidth = 1; drawFantasy(); ctx.stroke(); ctx.restore(); } } } }
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: 480; height: 480; visible: true; Rectangle { anchors.fill: parent Canvas { id: canv width: 320; height: 320; onPaint: { var ctx = getContext("2d"); ctx.strokeStyle= "blue"; ctx.lineWidth = 15; var gradient = ctx.createLinearGradient(canv.width, canv.height, 0, 0); gradient.addColorStop(0, "Indigo"); gradient.addColorStop(0.5, "Bisque"); gradient.addColorStop(1, "ForestGreen"); ctx.fillStyle = gradient; ctx.fillRect(0, 0, canv.width, canv.height); ctx.strokeRect(0, 0, canv.width, canv.height); } } } }
Для получения событий мыши служат специальные элементы - MouseArea, по сути просто прямоугольные области, в которых осуществляется ввод информации от мыши.
import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Layouts 1.12 ApplicationWindow { width: 300; height: 300; visible: true; Rectangle { anchors.fill: parent color: "lightgreen" Text { id: txt anchors.centerIn: parent text: "<h1>This is text<br>Click here</h1>" horizontalAlignment: Text.AlignHCenter } MouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: { if(mouse.button == Qt.LeftButton) parent.color= "red" else parent.color= "blue" } onReleased: parent.color= "lightgreen" } } }
Так же, можно использовать свойство containsMouse, для обнаружения находится ли курсор над областью.
Аналогично можно использовать свойства onEntered и onExit.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 300; height: 300; visible: true; Rectangle { anchors.fill: parent color: mousearea.containsMouse ? "red" : "lightgreen" Text { anchors.centerIn: parent text: "<h1>Hover me</h1>" } MouseArea { id: mousearea anchors.fill: parent hoverEnabled: true } } }
Сигналы в QML это события, которые уже прикреплены к свойствам, с кодом исполнения в них, эти свойства называются с префиксом on и являются по сути слотами.
Можно определять собственные сигналы:
signal <name>[(<type> <value>, …)]
К каждому такому сигналу автоматически создастся соответствующий обработчик (слот), с префиксом on.
Насколько я понимаю, вызвать наш сигнал может только какое то действие т.е. стандартный сигнал (точнее его обработчик on..), поэтому любой собственный сигнал будет так или иначе связан с уже существующим, стандартным сигналом.., плюс есть как минимум в том, что наши собственные сигналы будут доступны на уровнях выше т.е. извне, в случае например объявления объекта в отдельном файле.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 300; height: 300; visible: true; Rectangle { anchors.fill: parent color: mousearea.containsMouse ? "red" : "lightgreen" signal myMouseSignal(int x, int y) onMyMouseSignal: { txt.text= "<h1>X:"+x +"; Y:"+y +"</h1>" } Text { id: txt anchors.centerIn: parent } MouseArea { anchors.fill: parent hoverEnabled: true onMouseXChanged: parent.myMouseSignal(mouseX, mouseY) onMouseYChanged: parent.myMouseSignal(mouseX, mouseY) } } }
// Файл button.qml import QtQuick 2.0 BorderImage { property alias text: txt.text signal clicked; source: "qrc:/button.png" width: txt.width +15 height: txt.height +15 border {left: 15; top: 12; right: 15; bottom: 15} Text { id: txt color: "white" anchors.centerIn: parent } MouseArea { anchors.fill: parent onClicked: parent.clicked(); onPressed: parent.source= "button-press.png" onReleased: parent.source= "button.png" } } // Основной файл import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 150; height: 100; visible: true; Rectangle { anchors.fill: parent Button { anchors.centerIn: parent text: "Click this" onClicked: text= "Clicked" } } }
В основном ввод с клавиатуры обрабатывается двумя элементами: TextInput (однострочный) и TextEdit (многострочный).
Размер элемента будет соответствовать введенному тексту, что бы при пустом вводе элемент не исчезал, нужно задавать мин.ширину
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: txt.width + 20; height: 100; visible: true; Rectangle { anchors.fill: parent TextInput { id: txt anchors.centerIn: parent color: "red" text: "Text in this" font.pixelSize: 32 focus: true } } }
Если на форме один элемент, он получает фокус автоматом, далее, фокус можно изменить ручным выбором мышкой либо табом. Програмно можно воспользоваться свойством focus.
Нетекстовые элементы так же могут иметь фокус.
Для управления порядком фокуса табом, используется т.н. прикрепляемое свойство «KeyNavigation.tab: <FocusThisElement>». В этом свойстве так же доступны клавиши типа KeyNavigation.left, KeyNavigation.right, KeyNavigation.up, KeyNavigation.down и т.д.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 200; height: 80; visible: true; Rectangle { anchors.fill: parent TextEdit { anchors { left: parent.left right: parent.horizontalCenter top: parent.top bottom: parent.bottom } text: "Text1\nText1\nText1" font.pixelSize: 20 color: focus ? "red":"black" focus: true } TextEdit { anchors { left: parent.horizontalCenter right: parent.right top: parent.top bottom: parent.bottom } text: "Text2\nText2\nText2" font.pixelSize: 20 color: focus ? "red":"black" } } }
С помощью прикрепляемого свойства Keys можно получить доступ к событиям клавиатуры, с полной информацией о событии.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 200; height: 80; visible: true; Rectangle { anchors.fill: parent Text { x: 20; y: 20; text: "Move this text" horizontalAlignment: Text.AlignHCenter Keys.onLeftPressed: x -= 3 Keys.onRightPressed: x += 3 Keys.onUpPressed: y -= 3 Keys.onDownPressed: y += 3 focus: true } } }
При помощи Keys.forwardTo можно пересылать события другим элементам, для дальнейшей обработки.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 200; height: 80; visible: true; Rectangle { anchors.fill: parent Text { x: 20; y: 20; text: "Move this text" horizontalAlignment: Text.AlignHCenter focus: true Keys.onPressed: { if(event.key === Qt.Key_Left) { x -= 3; } else if(event.key === Qt.Key_Right) { x += 3; } else if(event.key === Qt.Key_Down) { y += 3; } else if(event.key === Qt.Key_Up) {y -= 3; } else if(event.key === Qt.Key_Plus) {font.pixelSize++; } else if(event.key === Qt.Key_Minus) {font.pixelSize--; } } } } }
Область региона- MultiPointTouchArea. Он содержит в себе элементы обработки события касания- TouchPoint, их должно быть столько, сколько одновременных касаний мы собираемся принимать, его можно сравнить с MouseArea.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 400; height: 400; visible: true Rectangle { anchors.fill: parent color: "black" MultiPointTouchArea { anchors.fill: parent minimumTouchPoints: 1 maximumTouchPoints: 5 touchPoints: [ TouchPoint {}, TouchPoint {}, TouchPoint {}, TouchPoint {}, TouchPoint {} ] Repeater { model: parent.touchPoints Rectangle { color: "white" x: modelData.x; y: modelData.y width: 30; height: 30 visible: modelData.pressed } } } } }
Так же, у TouchPoint есть следующие св-ва:
pressed | При касании == true |
pressure | Сила нажатия (не все устр-ва поддерживают) |
previous{X,Y} | Пред координаты касания |
start{X,Y} | Начальные координаты касания |
x,y | Текущие координаты касания |
Для анимации свойств существует элемент PropertyAnimation, с ним можно менять сразу несколько свойств одновременно.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 400; height: 400; visible: true Rectangle { anchors.fill: parent color: "lightgreen" Image { id: img x: 0; y: 0; source: "qrc:/button.png" } PropertyAnimation { target: img properties: "x,y" // Начальное и конечное значение для св-в from: 0; to: 400 - img.height // Длительность мс duration: 1500 running: true loops: Animation.Infinite // Режим. скорость и т.д. есть интерактивный редактор easing.type: Easing.OutExpo } } }
Более эффективная реализация для real и int.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 300; height: 100; visible: true Rectangle { id: par anchors.fill: parent color: "lightgreen" Rectangle { x: 0; y: 0; height: 100 color: "red" NumberAnimation on width { id: anim1 from: 300; to: 0 duration: 2000 easing.type: Easing.InOutCubic onStopped: { anim2.start() } } NumberAnimation on width { id: anim2 from: 0; to: 300 duration: 2000 easing.type: Easing.InOutCubic running: false onStopped: { anim1.start() } } } } }
ColorAnimation управляет изменением цвета, так же используется from и to.
import QtQuick 2.12; import QtQuick.Controls 2.2 ApplicationWindow { width: 300; height: 100; visible: true Rectangle { anchors.fill: parent ColorAnimation on color { from: "lightgreen" to: "red" duration: 1500 running: true loops: Animation.Infinite } } }