Qt Quick - простая анимация
(релиз Qt SDK на момент написания данной статьи - 1.1.4)
В этой статье я вас покажу простой пример того, как на языке QML можно сделать анимированное передвижение объектов.
Для начала небольшая вводная. В этой статье мы будем оперировать таким понятие как State (состояние). Любой объект в QML (будь то Rectangle, TextInput, Text и тыды) может иметь несколько состояний.
Например мы можем определить для прямоугольника 2 состояния:
1. Начальное, когда он размером 500 на 500 и имеет серый цвет
2. Второе состояние, когда он будет красного цвета размером 700 на 100
3. Ещё одно состояние, когда он будет скажем зеленый, размером 300 на 300
Как это делается?
Для начального состояния мы создаём простой прямоугольник, как мы это делали в статье http://easy-qt.blogspot.com/2012/01/hello-world-v3-qt-quick-edition.html
Так как прямоугольник верхнего уровня задаёт размеры окна, сначала мы создадим окно, а внутрь него поместим наш прямоугольник из примера. Изменим его свойства таким образом, чтобы оно подходило под наш пример:
У нас добавились 2 ранее не описанных поля: id и color. color - цвет прямоугольника, а ID - идентификатор, через который мы в дальнейшем сможем работать с нашим прямоугольником.import QtQuick 1.0 Rectangle { width: 800 height: 600 Rectangle { id: rec width: 500 height: 500 color: "gray" } }
Как видите, наш прямоугольник уже находится в начальном состоянии и нам не потребуется описывать его в дальнейшем.
Теперь нам необходимо задать второе и третье его состояние. В состояниях мы указываем те свойства, которые должны поменяться. Записывается это следующим образом:
Я думаю вам бы теперь хотелось посмотреть на это самое состояние. Будем переходить в это состояние по клику мыши на этом самом прямоугольнике. Для этого нам необходимо добавить в прямоугольник область обработки действий мыши, и когда будем кликать в этой области, переводить объект во второе состояние.import QtQuick 1.0 Rectangle { width: 800 height: 600 Rectangle { id: rec width: 500 height: 500 color: "gray" //--------------------------------------------------------------------- // Новый текст states: [ State { name: "StateDva" PropertyChanges { target: rec width: 700 height: 100 color: "red" } } ] //--------------------------------------------------------------------- } }Здесь мы определяем свойство states нашего прямоугольника. Как видите, мы создаём новый объект типа State, задаём его имя и указываем что меняется в этом состоянии (Property Changes).Свойства мы задали в соответствии с желаемым вторым состоянием.
import QtQuick 1.0
Rectangle
{
width: 800
height: 600
Rectangle {
id: rec
width: 500
height: 500
color: "gray"
MouseArea
{
anchors.fill: parent
onClicked: rec.state = "StateDva"
}
//---------------------------------------------------------------------
// Новый текст
states: [
State {
name: "StateDva"
PropertyChanges {
target: rec
width: 700
height: 100
color: "red"
}
}
]
//---------------------------------------------------------------------
}
}
Теперь вы можете запустить приложение, и кликнуть по прямоугольнику. Как видите, переход происходит. Но на мой взгляд он смотрится как-то убогенько. Сделаем это дело плавным и красивым. Для этого мы добавим переход.
import QtQuick 1.0
Rectangle
{
width: 800
height: 600
Rectangle {
id: rec
width: 500
height: 500
color: "gray"
MouseArea
{
anchors.fill: parent
onClicked: rec.state = "StateDva"
}
states: [
State {
name: "StateDva"
PropertyChanges {
target: rec
width: 700
height: 100
color: "red"
}
}
]
//---------------------------------------------------------------------
// Новый текст
transitions: [
Transition {
from: ""
to: "StateDva"
NumberAnimation {
target: rec
properties: "height, width"
duration: 800
}
}
]
//---------------------------------------------------------------------
}
}
Аналогично свойству states: мы создаём новый объект для свойства transitions. Внутри мы определяем, для какого перехода будет применяться данная анимация (from, to). Пустое название состояния - изначальное состояние объекта. В качестве имени состояния вы также можете указать "*". Звезда означает - любое состояние.
т. е. запись
from: "*" to: "*"будет обозначать "При любом переходе".
Внутри мы указываем числовую анимацию (NumberAnimation) для объекта, свойств, и собственно время этой самой анимации. Пробуем.
Прямоугольник конечно изменяется красиво, но цвет меняется слишком резко. Значит надо добавить анимацию для цвета:
import QtQuick 1.0 Rectangle { width: 800 height: 600 Rectangle { id: rec width: 500 height: 500 color: "gray" MouseArea { anchors.fill: parent onClicked: rec.state = "StateDva" } states: [ State { name: "StateDva" PropertyChanges { target: rec width: 700 height: 100 color: "red" } } ] transitions: [ Transition { from: "" to: "StateDva" NumberAnimation { target: rec properties: "height, width" duration: 800 } //--------------------------------------------------------------- // Новый текст ColorAnimation { target: rec duration: 800 } } ] //--------------------------------------------------------------------- } }
Как вы можете видеть, внутри одного перехода находятся несколько типов анимаций. Их можно выполнять как параллельно, так и по очереди, но об этом в следующий раз.
Добавим третье состояние:
import QtQuick 1.0 Rectangle { width: 800 height: 600 Rectangle { id: rec width: 500 height: 500 color: "gray" MouseArea { anchors.fill: parent onClicked: rec.state = "StateDva" } states: [ State { name: "StateDva" PropertyChanges { target: rec width: 700 height: 100 color: "red" } } //--------------------------------------------------------- // Новый текст , State { name: "StateTri" PropertyChanges { target: rec width: 300 height: 300 color: "green" } } //----------------------------------------------------------- ] transitions: [ Transition { from: "" to: "StateDva" NumberAnimation { target: rec properties: "height, width" duration: 800 } ColorAnimation { target: rec duration: 800 } } ] } }Ну а теперь нам надо посмотреть на это состояние, изменим обработки MouseArea по клику мыши, добавив условный оператор.Теперь у вас есть прямоугольник с тремя состояниями. Попробуйте поэкспериментировать с Переходами (испробуйте *, добавьте ещё один передох и тыды).onClicked: if (rec.state == "") rec.state = "StateDva" else rec.state = "StateTri"
Этот комментарий был удален автором.
ОтветитьУдалитьЗапутался в скобках и еще надо же прописать, что после одного State надо поставить "," и только потом писать другой State, также и с Transition (добавил Transition еще и к переходу на зеленый квадрат) долго искал эту запятую!))
ОтветитьУдалитьА как произвольную фигуру рисовать?
Базовых путей для построения произвольной фигуры к сожалению нет.
ОтветитьУдалитьМожно либо добавить картинку, либо делать рисование через QObject, но оба пути не ахти :(
Хотелось бы увидеть побольше простых уроков с подробными объяснениями, так сказать, для новичков и среднего класса.
ОтветитьУдалитьНапример в одном из уроков видел запись следующего характера:
(К примеру, уже не помню где видел)
.h
QLabel *lbl; //знающие поймут, а для остальных я потом расскажу, и так и не рассказано. Понятно, что это указатель на объект класса, понятно что он дан в .h для того чтобы объект класса был виден в контексте программы. Но почему именно указатель на объект, почему не объект? Ну и т.п.
Очень интересный урок! Спасибо!
ОтветитьУдалитьПри попытке прописать переходы не для всех статусов сразу, а по отдельности, программа выдавала ошибку.
Понял, что дело в неверном "синтаксисе". Сразу не уяснил, что нужно ставить запятые между операторами.
Далее, как нужно:
Transitions: [
Transition{...}
,
Transition{...}
,
Transition{...}
]
p.s. может кому-то покажется дикой глупостью, но промучился я в поисках моей ошибки около часа. Может кому-то поможет.