I want to animate text on SplashScreen but it don't work but this qml animation work but animation on scale works
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
Page{
id:splashPage
Component.onCompleted: {
txtAnimation.start();
}
ColumnLayout{
id:clm
anchors.fill: parent
Image {
id: icon
source: "/images/icon.png"
Layout.preferredHeight: 200
Layout.preferredWidth: 200
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: (clm.implicitHeight-icon.height)/2
}
Text{
id:txt
text: "Title under application icon"
Layout.alignment: Qt.AlignHCenter|Qt.AlignTop
}
Item {
Layout.fillHeight: true
}
}
SequentialAnimation{
id:txtAnimation
NumberAnimation {
target: txt
duration: 1000
easing.type: Easing.OutElastic
properties: "x"
from: -1000
}
SequentialAnimation {
loops: Animation.Infinite
alwaysRunToEnd: true
PauseAnimation{
duration: 600
}
PropertyAnimation {
target: txt
property: "scale"
to: 1.0
duration: 100
}
PropertyAnimation {
target: txt
property: "scale"
to: 0.85
duration: 400
}
PropertyAnimation {
target: txt
property: "scale"
to: 1
duration: 100
}
}
}
}
When I change the NumberAnimation to below it works But in ColumnLayout it don't have x property
NumberAnimation {
target: txt
duration: 1000
easing.type: Easing.OutElastic
properties: "x"
from: -1000
to:25
}
I changed the code like below but it don't work too
Text{
id:txt
text: "Title"
color: "#7f0000"
Layout.alignment: Qt.AlignHCenter|Qt.AlignTop
Behavior on x{
NumberAnimation {
duration: 1000
// easing.type: Easing.OutElastic
}
}
}
The fact that your animation works when you set the to property, but doesn't work without it shows us that it's necessary in this case. So you just need to set it to a value that keeps the text centered horizontally. For that, try this:
to: (clm.width - txt.width) / 2
Related
I need to move an object by the clock and counterclockwise sequentially. But the for loop works differently, it only moves in the latter direction. When you click on the button, the object must first turn clockwise, and then counterclockwise. Maybe there is some kind of delay when performing the animation? How can I do it?
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick3D 1.15
import QtQuick.Controls 2.14
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
visibility: "Maximized"
property int scl: 5
property int angle: 360
Node{
id: standAloneScene
DirectionalLight {
ambientColor: Qt.rgba(1.0, 1.0, 1.0, 1.0)
}
Node {
id: sphere
Model {
id: model_sphere
source: "#Cube"
x: 200
y: 100
z: 0
materials: [
DefaultMaterial {
diffuseColor: Qt.rgba(0.053, 0.130, 0.219, 0.75)
}
]
}
}
ParallelAnimation{
id: start
running: false
NumberAnimation {
target: sphere
property: "eulerRotation.y"
to: angle
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: model_sphere
property: "eulerRotation.y"
to: 2*angle
duration: 2000
easing.type: Easing.InOutQuad
}
}
OrthographicCamera {
id: cameraOrthographicFront
eulerRotation.y: 45
eulerRotation.x: -45
x: 600
y: 800
z: 600
}
}
Rectangle {
id: view
anchors.top: parent.top
anchors.left: parent.left
width: parent.width
height: parent.height
color: "#848895"
border.color: "black"
View3D {
id: topLeftView
anchors.fill: parent
importScene: standAloneScene
camera: cameraOrthographicFront
}
Button {
id: posmoveZ
width: view.width/8
height: view.height/16
anchors.top: view.top
anchors.right: view.right
text: "start"
font.pixelSize: height
onClicked: {
for(var i=0; i<6; i++){
if(i % 2 == 0){
angle = 360
}
else{
angle = -360
}
start.restart();
}
}
}
}
}
The simplest answer to your problem is put your animations inside a SequentialAnimation, i.e.
SequentialAnimation {
loops: 3
ParallelAnimation {
id: clockwise
NumberAnimation { /* ... */ }
NumberAnimation { /* ... */ }
}
ParallelAnimation {
id: counterClockwise
NumberAnimation { /* ... */ }
NumberAnimation { /* ... */ }
}
}
Also, you should let QML use the default width and height of a Button. Here's the complete solution:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import QtQuick3D 1.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
visibility: "Maximized"
property int scl: 5
property int angle: 360
Node{
id: standAloneScene
DirectionalLight {
ambientColor: Qt.rgba(1.0, 1.0, 1.0, 1.0)
}
Node {
id: sphere
Model {
id: model_sphere
source: "#Cube"
x: 200
y: 100
z: 0
materials: [
DefaultMaterial {
diffuseColor: Qt.rgba(0.053, 0.130, 0.219, 0.75)
}
]
}
}
SequentialAnimation {
id: sequentialAnimation
loops: 3
ParallelAnimation{
id: clockwise
running: false
property int count: 3
NumberAnimation {
target: sphere
property: "eulerRotation.y"
from: 360
to: 0
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: model_sphere
property: "eulerRotation.y"
from: 720
to: 0
duration: 2000
easing.type: Easing.InOutQuad
}
}
ParallelAnimation{
id: counterClockwise
running: false
NumberAnimation {
target: sphere
property: "eulerRotation.y"
from: 0
to: 360
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: model_sphere
property: "eulerRotation.y"
from: 0
to: 720
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
OrthographicCamera {
id: cameraOrthographicFront
eulerRotation.y: 45
eulerRotation.x: -45
x: 600
y: 800
z: 600
}
}
Rectangle {
id: view
anchors.top: parent.top
anchors.left: parent.left
width: parent.width
height: parent.height
color: "#848895"
border.color: "black"
View3D {
id: topLeftView
anchors.fill: parent
importScene: standAloneScene
camera: cameraOrthographicFront
}
Button {
id: posmoveZ
anchors.top: view.top
anchors.right: view.right
anchors.margins: 10
text: "start"
font.pixelSize: height
enabled: !clockwise.running && !counterClockwise.running
onClicked: {
sequentialAnimation.restart();
}
}
}
}
How to change cursor color and probably width in QML TextField element? Let say we have following one:
import QtQuick 2.12
import QtQuick.Controls 2.12
TextField {
id: control
placeholderText: qsTr("Enter description")
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
color: control.enabled ? "transparent" : "#353637"
border.color: control.enabled ? "#21be2b" : "transparent"
}
}
How to make cursor color green or blue or whatever? Thanks!
You have to set Rectangle with the color you want as the cursor through the cursorDelegate since TextField inherits from TextInput and therefore shares that property.
import QtQuick 2.12
import QtQuick.Controls 2.12
TextField {
id: control
placeholderText: qsTr("Enter description")
cursorDelegate: Rectangle {
visible: control.cursorVisible
color: "salmon"
width: control.cursorRectangle.width
}
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
color: control.enabled ? "transparent" : "#353637"
border.color: control.enabled ? "#21be2b" : "transparent"
}
}
#eyllanesc provides a very good answer, but I want to point that the blinking behavior will not be preserved when you define a custom cursorDelegate.
If you want to have the blinking of the cursor. It can be done using an animation:
import QtQuick 2.12
import QtQuick.Controls 2.12
TextField {
id: control
placeholderText: qsTr("Enter description")
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
color: control.enabled ? "transparent" : "#353637"
border.color: control.enabled ? "#21be2b" : "transparent"
}
cursorDelegate: Rectangle {
id: cursor
visible: false
color: "salmon"
width: control.cursorRectangle.width
SequentialAnimation {
loops: Animation.Infinite
running: control.cursorVisible
PropertyAction {
target: cursor
property: 'visible'
value: true
}
PauseAnimation {
duration: 600
}
PropertyAction {
target: cursor
property: 'visible'
value: false
}
PauseAnimation {
duration: 600
}
onStopped: {
cursor.visible = false
}
}
}
}
I am adding Animation to my project and most of the UI is dynamic. Currently, i am not able to add animation to the Component while destroying. Following is the test application code which describes the same:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property bool removeClicked : true
Row{
anchors.bottom: parent.bottom
spacing:20
Button{
text:"Add"
onClicked: {
removeClicked = false
comp.createObject(myrow)
}
}
Button{
id:remBtn
text:"Remove"
onClicked: {
removeClicked = true
myrow.children[0].destroy() //Destroy the object
}
}
}
Row{
id:myrow
height:40
spacing:20
}
Component{
id:comp
Rectangle{
width:20
height:30
color: "red"
NumberAnimation on opacity{
id: destroyAnimation
from :removeClicked ? 1:0
to: removeClicked ? 0:1
duration: 1000
}
}
}
}
Any help will be Appreciated!!!
Shou should perform the animation before calling destroy on your dynamically created items. You could use a SequentialAnimation, combined with a ScriptAction to do so.
Here's a small example (the dynamic balls get destroyed when one clicks on them).
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
visible: true
width: 640
height: 480
Button{
text:"Add"
anchors.centerIn: parent
onClicked: {
comp.createObject(parent)
}
}
Component{
id:comp
Rectangle{
id: ball
height:30
width:height
radius: height/2
x: Math.random()*parent.width-width
y: Math.random()*parent.height-height
color: Qt.hsla(Math.random(), 0.5, 0.5, 1)
opacity: 0
Component.onCompleted: opacity = 1
Behavior on opacity{ NumberAnimation {}}
SequentialAnimation
{
id: destroyAnim
ScriptAction{script: ball.opacity = 0}
NumberAnimation{target: ball; property:"scale"; to: 5}
ScriptAction{script: ball.destroy()}
}
MouseArea
{
anchors.fill: parent
onClicked:destroyAnim.start()
}
}
}
}
Is there anything for animating text changes? there is already animations for property changes, for example this code do the animation for properties opacity, width and scale and whenever they changed by states, they will get animations.
NumberAnimation {
properties: "opacity, width, scale, visible"
easing.type: Easing.OutBack; duration:500
}
However i didn't find anything for text change, for example counting from N to N+1 became animating (eg. fading out old value and fading new one). how i can animating text changes?
For this usecase I use Behavior with a custom Animation :
//FadeAnimation.qml
import QtQuick 2.0
SequentialAnimation {
id: root
property QtObject target
property string fadeProperty: "scale"
property int fadeDuration: 150
property alias outValue: outAnimation.to
property alias inValue: inAnimation.to
property alias outEasingType: outAnimation.easing.type
property alias inEasingType: inAnimation.easing.type
property string easingType: "Quad"
NumberAnimation { // in the default case, fade scale to 0
id: outAnimation
target: root.target
property: root.fadeProperty
duration: root.fadeDuration
to: 0
easing.type: Easing["In"+root.easingType]
}
PropertyAction { } // actually change the property targeted by the Behavior between the 2 other animations
NumberAnimation { // in the default case, fade scale back to 1
id: inAnimation
target: root.target
property: root.fadeProperty
duration: root.fadeDuration
to: 1
easing.type: Easing["Out"+root.easingType]
}
}
Please note that it can be done without all the added properties, but I have them to enable easy customization.
An example usage could be :
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
anchors.centerIn: parent
color: "red"
width: 100
height: width
radius: width/2
Text {
id: textItem
anchors.centerIn: parent
font.pixelSize: 30
color: "white"
property int foo: 0
// ### Important part ###
text: foo
Behavior on foo {
FadeAnimation {
target: textItem
}
}
// ######################
}
MouseArea {
anchors.fill: parent
onClicked: textItem.foo++
}
}
}
Output : https://zippy.gfycat.com/SilentImpressiveChameleon.webm
The fadeProperty is scale by default but it also works great with opacity.
EDIT :
I've implemented this as ready-to-use components in https://github.com/okcerg/quickbehaviors
I would suggest something like the following AnimatedText.qml:
import QtQuick 2.5
Item{
property real progress: 0.0
property string text0
property string text1
Text{
text: text0
opacity: 1.0 - progress
}
Text{
text: text1
opacity: progress
}
}
Can be used as follows:
AnimatedText{
text0: "First text"
text1: "Second text"
NumberAnimation on progress {
from: 0.0
to: 1.0
duration: 5000
}
}
I created a custom Item for this purpose with fade animation. You can edit it for any animation:
AnimatedText.qml
import QtQuick 2.7
Item {
id: root
width: Math.max(txt1.width, txt2.width);
height: Math.max(txt1.height, txt2.height);
property string text: ""
property int currentActiveTxt: 1
property real pointSize: 20
Text {
id: txt1
font { pointSize: root.pointSize }
}
Text {
id: txt2
font { pointSize: root.pointSize }
}
onTextChanged: {
if(currentActiveTxt == 1) {
txt2.text = root.text;
currentActiveTxt = 2;
root.state = "txt2 is active";
} else {
txt1.text = root.text;
currentActiveTxt = 1;
root.state = "txt1 is active";
}
}
states: [
State {
name: "txt1 is active"
PropertyChanges {
target: txt1
opacity: 1.0
}
PropertyChanges {
target: txt2
opacity: 0.0
}
},
State {
name: "txt2 is active"
PropertyChanges {
target: txt1
opacity: 0.0
}
PropertyChanges {
target: txt2
opacity: 1.0
}
}
]
state: "txt1 is active"
transitions: [
Transition {
from: "txt1 is active"
to: "txt2 is active"
NumberAnimation {
property: "opacity"
duration: 200
}
},
Transition {
from: "txt2 is active"
to: "txt1 is active"
NumberAnimation {
property: "opacity"
duration: 200
}
}
]
}
Sample usage:
Window {
id:root
visible: true
width: 340
height: 480
title: qsTr("Hello World")
AnimatedText {
id: txt
pointSize: 30
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: 10
text: ":)"
}
Timer {
interval: 1000
running: true
repeat: true
property int i: 0
onTriggered: txt.text = i++;
}
}
I wonder how to make smooth transitions betwen image sources in QML, I try
import QtQuick 1.1
Image {
id: rect
source: "quit.png"
smooth: true
MouseArea {
id: mouseArea
anchors.fill: parent
anchors.margins: -10
hoverEnabled: true //this line will enable mouseArea.containsMouse
onClicked: Qt.quit()
}
states: State {
name: "mouse-over"; when: mouseArea.containsMouse
PropertyChanges { target: rect; scale: 0.8; source :"quit2.png" }
}
transitions: Transition {
NumberAnimation { properties: "scale, source"; easing.type: Easing.InOutQuad; duration: 1000 }
}
}
But It does not work on source as a transition just as final state change.. so I wonder how to make one image source fade into andothe and back?
You want the first image to fade out into the other? How about if you place two Image objects on top of each other, then animate the opacity property?
EDIT: This worked for me (I'm using QtQuick 1.0 because my Qt Creator installation is a bit outdated):
import QtQuick 1.0
Rectangle {
Image {
id: rect
source: "quit.png"
smooth: true
opacity: 1
MouseArea {
id: mouseArea
anchors.fill: parent
anchors.margins: -10
hoverEnabled: true //this line will enable mouseArea.containsMouse
onClicked: Qt.quit()
}
states: State {
name: "mouse-over"; when: mouseArea.containsMouse
PropertyChanges { target: rect; scale: 0.8; opacity: 0}
PropertyChanges { target: rect2; scale: 0.8; opacity: 1}
}
transitions: Transition {
NumberAnimation { properties: "scale, opacity"; easing.type: Easing.InOutQuad; duration: 1000 }
}
}
Image {
id: rect2
source: "quit2.png"
smooth: true
opacity: 0
anchors.fill: rect
}
}
To the question in your comment: you can place the image exactly on top of the other by copying the anchors thru anchors.fill: rect
Here is also a simple scroll transition between images:
import QtQuick 2.6
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
id: imageRect
anchors.centerIn: parent
width: 240
height: 320
clip: true
property int currentIndex: 0
property var imageSources: [ "imageLeft.jpg", "imageCenter.jpg" ]
Repeater {
model: imageRect.imageSources
Image {
id: image
width: parent.width
height: parent.height
x: index * parent.width - imageRect.currentIndex * parent.width
fillMode: Image.PreserveAspectFit
source: imageRect.imageSources[index]
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
}
}
}
Button {
id: leftButton
anchors.bottom: parent.bottom
text: "left"
onClicked: if(imageRect.currentIndex > 0) imageRect.currentIndex--
}
Button {
id: rightButton
anchors.bottom: parent.bottom
anchors.left: leftButton.right
text: "right"
onClicked: if(imageRect.currentIndex < imageRect.imageSources.length - 1) imageRect.currentIndex++
}
Button {
id: addButton
anchors.bottom: parent.bottom
anchors.left: rightButton.right
text: "+"
onClicked: imageRect.imageSources = [ "imageLeft.jpg", "imageCenter.jpg" , "imageRight.jpg" ]
}
}