Инструменты пользователя

Инструменты сайта


develop:qt:quick2

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
develop:qt:quick2 [2021/08/23 11:22]
admin создано
develop:qt:quick2 [2021/08/31 15:21] (текущий)
admin
Строка 1: Строка 1:
-====== Qt Quick: Ввод, Анимация, Преставление, С++ ======+====== Qt Quick: Изображения, Ввод, Анимация ====== 
 + 
 + 
 +===== Элементы графики ===== 
 +==== Растровые изображения ==== 
 + 
 +Можно использовать форматы: **JPG****PNG** и **SVG**.\\ 
 +  
 +=== Элемент Image === 
 +Этот элемент отображает файл изображения, указанный в свойстве **source**, файл может находится как локально так и в сети.\\ 
 +Есть интерактивный редактор для изменения свойств.\\ 
 +Свойствами можно подвергать изображение трансформациям, типа увеличение/уменьшение (**scale**), поворот (**rotation**), сглаживание (**smooth**).\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Изображение с уменьшением, поворотом и сглаживанием</summary> 
 +<code QML> 
 +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 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 + 
 +Для более тонкой настройки трансформации, ее можно задавать списками (в квадратных скобках).\\ 
 +<details> 
 +<summary>:!: Пример: Аналогичнотолько трансформацию задаем двумя списками свойству **transform**</summary> 
 +<code QML> 
 +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 
 +                } 
 +            ] 
 +        } 
 +    } 
 +
 + 
 +</code> 
 +</details> 
 + 
 + 
 +Добавим элемент загрузки **BusyIndicator** 
 +<details> 
 +<summary>:!: Пример: Загрузка и отображение изображения из web</summary> 
 +<code QML> 
 +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 
 +                {} 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +=== BorderImage === 
 + 
 +Элемент для нормального масштабирования графики, особенно полезно при закругленных углах (кнопок и т.д.). Элемент разбивает изображение на девять частей.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Масштабируемое изображение кнопки, с закругленными углами</summary> 
 +<code QML> 
 +import QtQuick 2.12 
 + 
 +BorderImage 
 +
 +    source: "" 
 +    width: 100; height: 45 
 +    border {left: 30; top: 15; right: 30; bottom: 15} 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Градиент ==== 
 +---- 
 +В QML есть только один градиент - линейный, если нужен другой, можно воспользоваться трансформацией.\\ 
 +Для создания, нужно свойству **gradient** присвоить элемент **Gradient**, он содержит точки останова (**GradientStop**) с позициями от 0 до 1.\\ 
 + 
 +Создание градиентов может потребовать много ресурсов, поэтому эффективнее использовать изображение градиента.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Градиент с тремя точками останова, трансформирован в диагональ</summary> 
 +<code QML> 
 +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 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Рисование Canvas ==== 
 +---- 
 +**Canvas** представляет собой элемент холста, на котором можно выполнять растровые операции, по сути аналогичен **QPaintDevice**.\\ 
 +Сам QML описательный язык, поэтому алгоритмы рисования реализуются с использованием **JavaScript**, в свойстве обработки **onPaint**.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Прикольный узор, нарисованный на холсте</summary> 
 +<code QML> 
 +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(); 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +<details> 
 +<summary>:!: Пример: Градиент на холсте</summary> 
 +<code QML> 
 +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); 
 +            } 
 +        } 
 +    } 
 +}        
 +</code> 
 +</details> 
 + 
 + 
 +  
 +===== Пользовательский ввод ===== 
 +==== Область мыши ==== 
 +---- 
 +Для получения событий мыши служат специальные элементы - **MouseArea**, по сути просто прямоугольные области, в которых осуществляется ввод информации от мыши.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Нажатие левой и правой кнопок мыши</summary> 
 +<code QML> 
 +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" 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +Так же, можно использовать свойство **containsMouse**, для обнаружения находится ли курсор над областью.\\ 
 +Аналогично можно использовать свойства **onEntered** и **onExit**.\\ 
 +<details> 
 +<summary>:!: Пример: Обнаружение находится ли курсор над областью</summary> 
 +<code QML> 
 +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 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Сигналы ==== 
 +---- 
 +Сигналы в QML это события, которые уже прикреплены к свойствам, с кодом исполнения в них, эти свойства называются с префиксом **on** и являются по сути слотами.\\ 
 + 
 +Можно определять собственные сигналы:\\ 
 +**signal <name>[(<type> <value>, ...)]**\\ 
 +К каждому такому сигналу автоматически создастся соответствующий обработчик (слот), с префиксом **on**.\\ 
 + 
 +Насколько я понимаю, вызвать наш сигнал может только какое то действие т.е. стандартный сигнал (точнее его обработчик **on..**), поэтому любой собственный сигнал будет так или иначе связан с уже существующим, стандартным сигналом.., плюс есть как минимум в том, что наши собственные сигналы будут доступны на уровнях выше т.е. извне, в случае например объявления объекта в отдельном файле.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Сигнал движения курсора мыши</summary> 
 +<code QML> 
 +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) 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 + 
 +<details> 
 +<summary>:!: Пример: Собственный элемент+ передача сигнала наружу</summary> 
 +<code QML> 
 +// Файл 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" 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Ввод с клавиатуры ==== 
 +---- 
 +В основном ввод с клавиатуры обрабатывается двумя элементами: **TextInput** (однострочный) и **TextEdit** (многострочный).\\ 
 +Размер элемента будет соответствовать введенному тексту, что бы при пустом вводе элемент не исчезал, нужно задавать мин.ширину 
 + 
 + 
 +<details> 
 +<summary>:!: Пример: Простое поле ввода текста</summary> 
 +<code QML> 
 +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 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Фокус ==== 
 +---- 
 +Если на форме один элемент, он получает фокус автоматом, далее, фокус можно изменить ручным выбором мышкой либо табом. Програмно можно воспользоваться свойством **focus**.\\ 
 +Нетекстовые элементы так же могут иметь фокус.\\ 
 +Для управления порядком фокуса табом, используется т.н. прикрепляемое свойство "**KeyNavigation.tab: <FocusThisElement>**". В этом свойстве так же доступны клавиши типа **KeyNavigation.left**, **KeyNavigation.right**, **KeyNavigation.up**, **KeyNavigation.down** и т.д.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Два поля ввода, выделение их фокусировки</summary> 
 +<code QML> 
 +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" 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Сырой ввод ==== 
 +---- 
 +С помощью прикрепляемого свойства **Keys** можно получить доступ к событиям клавиатуры, с полной информацией о событии.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Перемещение элемента с помощью клавиш-стрелок</summary> 
 +<code QML> 
 +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 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +При помощи **Keys.forwardTo** можно пересылать события другим элементам, для дальнейшей обработки.\\ 
 +<details> 
 +<summary>:!: Пример: Так же, можно сделать это в одном обработчике</summary> 
 +<code QML> 
 +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--;
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Мультитач ==== 
 +---- 
 +Область региона- **MultiPointTouchArea**. Он содержит в себе элементы обработки события касания- **TouchPoint**, их должно быть столько, сколько одновременных касаний мы собираемся принимать, его можно сравнить с **MouseArea**.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Обработка пяти одновременных касаний</summary> 
 +<code QML> 
 +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:
 +            maximumTouchPoints:
 +            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 
 +                } 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +Так же, у **TouchPoint** есть следующие св-ва: 
 +| pressed | При касании == true | 
 +| pressure | Сила нажатия (не все устр-ва поддерживают) | 
 +| previous{X,Y} | Пред координаты касания | 
 +| start{X,Y} | Начальные координаты касания | 
 +| x,y | Текущие координаты касания | 
 + 
 +  
 +===== Анимация ===== 
 +==== Анимация при изменении свойств ==== 
 +---- 
 +Для анимации свойств существует элемент **PropertyAnimation**, с ним можно менять сразу **несколько свойств одновременно**.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Одновременное изменение **x** и **y**</summary> 
 +<code QML> 
 +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 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +=== Изменение числовых значений === 
 +---- 
 +Более эффективная реализация для **real** и **int**.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Изменение размера вложенного прямоугольника x2</summary> 
 +<code QML> 
 +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() 
 +                } 
 +            } 
 + 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +=== Изменение цвета === 
 +---- 
 +**ColorAnimation** управляет изменением цвета, так же используется **from** и **to**.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Изменение цвета</summary> 
 +<code QML> 
 +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 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +=== Поворот === 
 +---- 
 +**RotationAnimation** описывает поворот элемента.\\ 
 +Его свойство **direction** задает направление поворота: 
 +| RotationAnimation.Clockwise | по часовой (по умолчанию) | 
 +| RotationAnimation.Counterclockwise | против часовой | 
 +| RotationAnimationShortest | угол поворота в наименьшую сторону исходя из "from-to"
 + 
 +<details> 
 +<summary>:!: Пример: Поворот по часовой стрелке</summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 150; height: 150; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        Image 
 +        { 
 +            source: "qrc:/button.png" 
 +            anchors.centerIn: parent 
 +            smooth: true 
 +            RotationAnimation on rotation 
 +            { 
 +                from: 0 
 +                to: 360 
 +                duration: 2000 
 +                loops: Animation.Infinite 
 +                easing.type: Easing.InOutBack 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Анимация поведения ==== 
 +---- 
 +**Behavior** реагирует на изменение свойств элементов, соответственно в эти моменты может вызывать другую анимацию и т.д.\\ 
 +В следующем примере, **Behavior** реагирует на изменение **x** и **y** у изображения, внутри другой элемент анимации, изменение же свойств изображения вызывается из событиями мыши в **MouseArea** 
 + 
 +<details> 
 +<summary>:!: Пример: Анимация вызывается поведением </summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 360; height: 360; visible: true 
 +    Rectangle 
 +    { 
 +        id: rect 
 +        anchors.fill: parent 
 +        Image 
 +        { 
 +            id: img 
 +            x: 10; y: 10; 
 +            source: "qrc:/button.png" 
 +            smooth: true 
 +            Text 
 +            { 
 +                anchors.verticalCenter: img.verticalCenter 
 +                anchors.top: img.bottom 
 +                text: "Move cursor" 
 +            } 
 +            Behavior on x 
 +            { 
 +                NumberAnimation 
 +                { 
 +                    duration: 500 
 +                    easing.type: Easing.OutBack 
 +                } 
 +            } 
 +            Behavior on y 
 +            { 
 +                NumberAnimation 
 +                { 
 +                    duration: 500 
 +                    easing.type: Easing.OutBack 
 +                } 
 +            } 
 +        } 
 +        MouseArea 
 +        { 
 +            anchors.fill: rect 
 +            hoverEnabled: true 
 +            onMouseXChanged: img.x= mouseX 
 +            onMouseYChanged: img.y= mouseY 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Параллельные и последовательные анимации ==== 
 +---- 
 +Анимации могут быть объединены в группы, эти группы выполняются **последовательно** (SequentialAnimation) либо **параллельно** (ParallelAnimation). Группы могут быть вложенными друг в друга. Если элемент группы не указан, анимации выполняются параллельно.\\ 
 + 
 +<details> 
 +<summary>:!: Пример: Параллельная анимация. Увеличение размера и прозрачность</summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 360; height: 360; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        Image 
 +        { 
 +            id: img 
 +            source: "qrc:/button.png" 
 +            smooth: true 
 +            anchors.centerIn: parent 
 +        } 
 +        ParallelAnimation 
 +        { 
 +            NumberAnimation 
 +            { 
 +                target: img 
 +                properties: "scale" 
 +                from: 0.1 
 +                to: 3.0 
 +                duration: 2000 
 +                easing.type: Easing.InOutCubic 
 +            } 
 +            NumberAnimation 
 +            { 
 +                target: img 
 +                properties: "opacity" 
 +                from: 1.0 
 +                to: 0 
 +                duration: 2000 
 +            } 
 +            running: true 
 +            loops: Animation.Infinite 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 + 
 +<details> 
 +<summary>:!: Пример: Тоже самое, но немного другой подход </summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 360; height: 360; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        Image 
 +        { 
 +            id: img 
 +            source: "qrc:/button.png" 
 +            smooth: true 
 +            anchors.centerIn: parent 
 +            NumberAnimation on scale 
 +            { 
 +                from: 0.1 
 +                to: 3.0 
 +                duration: 2000 
 +                easing.type: Easing.InOutCubic 
 +                loops: Animation.Infinite 
 +            } 
 +            NumberAnimation on opacity 
 +            { 
 +                from: 1.0 
 +                to: 0 
 +                duration: 2000 
 +                loops: Animation.Infinite 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +Пример последовательной анимации: После нажатия мыши объект упадет вниз, повернется вокруг своей оси, полежит немного, затем поднимется обратно вверх: 
 + 
 +<details> 
 +<summary>:!: Пример: </summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 130; height: 450; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        Image 
 +        { 
 +            id: img 
 +            source: "qrc:/button.png" 
 +            smooth: true 
 +            Text 
 +            { 
 +                anchors.horizontalCenter: parent.horizontalAlignment 
 +                anchors.top: parent.bottom 
 +                text: "Click for do it" 
 +            } 
 +            MouseArea 
 +            { 
 +                anchors.fill: img 
 +                onClicked: anim.running= true 
 +            } 
 +            SequentialAnimation 
 +            { 
 +                id: anim 
 +                NumberAnimation 
 +                { 
 +                    target: img 
 +                    from: 20; to: 300; 
 +                    properties: "y" 
 +                    duration: 1000 
 +                    easing.type: Easing.OutBounce 
 +                } 
 +                RotationAnimation 
 +                { 
 +                    target: img 
 +                    from: 0; to: 360; 
 +                    properties: "rotation" 
 +                    duration: 1000 
 +                } 
 +                PauseAnimation {duration: 500} 
 +                NumberAnimation 
 +                { 
 +                    target: img 
 +                    from: 300; to: 20; 
 +                    properties: "y" 
 +                    duration: 1000 
 +                    easing.type: Easing.OutBounce 
 +                } 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Состояния и переходы ==== 
 +=== Состояния === 
 +---- 
 +Управлять состоянием можно при помощи элемента **State**, поддерживает наборы списков, описания элементов с набором их состояний.\\ 
 +Все объекты **обязательно** должны быть **именованными**.\\ 
 +Список состояний присваивается свойству **states** а необходимый набор присваивается свойству **state**, так и происходит смена состояний.\\ 
 +Изменение свойств внутри состояния перечисляется в в элементе **PropertyChanges** 
 + 
 +<details> 
 +<summary>:!: Пример: Два определенных состояния прямоугольника и смена между ними</summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 360; height: 360; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 + 
 +        Rectangle 
 +        { 
 +            id: rect 
 +            state: "State2" 
 +            Text 
 +            { 
 +                id: txt 
 +                anchors.centerIn: parent 
 +            } 
 +        } 
 +        states: 
 +        [ 
 +            State 
 +            { 
 +                name: "State1" 
 +                PropertyChanges 
 +                { 
 +                    target: rect 
 +                    color: "lightgreen" 
 +                    width: 150; height: 60; 
 +                } 
 +                PropertyChanges 
 +                { 
 +                    target: txt 
 +                    text: "State2: Click" 
 +                } 
 +            }, 
 +            State 
 +            { 
 +                name: "State2" 
 +                PropertyChanges 
 +                { 
 +                    target: rect 
 +                    color: "yellow" 
 +                    width: 200; height: 120; 
 +                } 
 +                PropertyChanges 
 +                { 
 +                    target: txt 
 +                    text: "State1: Click" 
 +                } 
 +            } 
 +        ] 
 +        MouseArea 
 +        { 
 +            anchors.fill: parent 
 +            onClicked: parent.state= (parent.state== "State1") ? "State2":"State1" 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Переходы ==== 
 +---- 
 +Свойство **transitions** задает список переходов, в списке задаем элементы **Transition**, каждый элемент содержит два момента: 
 +  * **from / to** - начальное/конечное состояние перехода (**States**, рассмотренные выше) 
 +  * **PropertyAnimation** - управление анимацией перехода 
 + 
 +<details> 
 +<summary>:!: Пример: Переход между состояниями</summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 360; height: 360; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        Rectangle 
 +        { 
 +            id: rect 
 +            width: 100; height: 100 
 +            color: "magenta" 
 +            state: "State1" 
 +            Text 
 +            { 
 +                anchors.centerIn: parent 
 +                text: "Click this" 
 +            } 
 +            MouseArea 
 +            { 
 +                anchors.fill: parent 
 +                onClicked: rect.state = (rect.state == "State1") ? "State2":"State1" 
 +            } 
 +            states: 
 +            [ 
 +                State 
 +                { 
 +                    name: "State1" 
 +                    PropertyChanges {target: rect; x: 0; y: 0} 
 +                }, 
 +                State 
 +                { 
 +                    name: "State2" 
 +                    PropertyChanges {target: rect; x: 200; y: 200} 
 +                } 
 +            ] 
 +            transitions: 
 +            [ 
 +                Transition 
 +                { 
 +                    from: "State1"; to: "State2"; 
 +                    PropertyAnimation 
 +                    { 
 +                        target: rect; 
 +                        properties: "x,y"; 
 +                        duration: 1000 
 +                        easing.type: Easing.OutBack 
 +                    } 
 +                }, 
 +                Transition 
 +                { 
 +                    from: "State2"; to: "State1"; 
 +                    PropertyAnimation 
 +                    { 
 +                        target: rect; 
 +                        properties: "x,y"; 
 +                        duration: 1000 
 +                        easing.type: Easing.InBounce 
 +                    } 
 +                } 
 +            ] 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +Если свойства перехода будут одинаковыми, тогда можно использовать **шаблонный переход**: 
 + 
 +<details> 
 +<summary>:!: Пример: Тоже самое только шаблонный переход</summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2 
 + 
 +ApplicationWindow 
 +
 +    width: 300; height: 300; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        Rectangle 
 +        { 
 +            id: rect 
 +            width: 100; height: 100 
 +            color: "magenta" 
 +            state: "State1" 
 +            Text 
 +            { 
 +                anchors.centerIn: parent 
 +                text: "Click this" 
 +            } 
 +            MouseArea 
 +            { 
 +                anchors.fill: parent 
 +                onClicked: rect.state = (rect.state == "State1") ? "State2":"State1" 
 +            } 
 +            states: 
 +            [ 
 +                State 
 +                { 
 +                    name: "State1" 
 +                    PropertyChanges {target: rect; x: 0; y: 0} 
 +                }, 
 +                State 
 +                { 
 +                    name: "State2" 
 +                    PropertyChanges {target: rect; x: 200; y: 200} 
 +                } 
 +            ] 
 +            transitions: 
 +            [ 
 +                Transition 
 +                { 
 +                    from: "*"; to: "*"; 
 +                    PropertyAnimation 
 +                    { 
 +                        target: rect; 
 +                        properties: "x,y"; 
 +                        duration: 1000 
 +                        easing.type: Easing.OutBack 
 +                    } 
 +                } 
 +            ] 
 +        } 
 +    } 
 +
 +</code> 
 +</details> 
 + 
 +  
 +==== Модуль частиц ==== 
 +---- 
 +Движок для работы с частицами, в роли частиц могут выступать картинки и т.д. 
 + 
 +<details> 
 +<summary>:!: Пример: Кнопкопад</summary> 
 +<code QML> 
 +import QtQuick 2.12; import QtQuick.Controls 2.2; import QtQuick.Particles 2.0 
 + 
 +ApplicationWindow 
 +
 +    width: 360; height: 360; visible: true 
 +    Rectangle 
 +    { 
 +        anchors.fill: parent 
 +        color: "MidnightBlue" 
 +        ParticleSystem 
 +        { 
 +            anchors.fill: parent 
 +            ImageParticle 
 +            { 
 +                source: "qrc:/button.png" 
 +            } 
 +            Emitter 
 +            { 
 +                width: parent.width 
 +                height: parent.height 
 +                anchors.bottom: parent.bottom 
 +                lifeSpan: 10000 
 +                sizeVariation: 16 
 +                emitRate: 20 
 +                velocity: AngleDirection 
 +                { 
 +                    angle: 90 
 +                    angleVariation: 10 
 +                    magnitude: 100 
 +                } 
 +            } 
 +        } 
 +    } 
 +
 +</code> 
 +</details>
  
develop/qt/quick2.1629717760.txt.gz · Последнее изменение: 2021/08/23 11:22 — admin