QML 动画效果详解

属性动画(PropertyAnimation)

PropertyAnimation是QML中最基础、最常用的动画类型,它可以对任何基于数字或颜色的属性进行动画化处理,实现平滑的过渡效果。

核心属性与用法

PropertyAnimation的主要属性如下表所示:

属性类型描述默认值
targetQtObject动画作用的目标对象父对象
propertystring要动画化的属性名必须指定
fromvariant动画起始值当前属性值
tovariant动画结束值必须指定
durationint动画持续时间(ms)250
easing.typeenumeration缓动曲线类型Easing.Linear
easing.amplitudereal弹性动画幅度1.0
easing.periodreal弹性动画周期0.3
loopsint循环次数1
runningbool是否自动运行false
alwaysRunToEndbool停止时是否完成动画false

基础示例

import QtQuick 2.15Rectangle {id: rectwidth: 100; height: 100color: "red"x: 0// 基本属性动画PropertyAnimation {target: rectproperty: "x"to: 200duration: 1000running: true}
}

缓动曲线示例

PropertyAnimation支持多种缓动曲线,可以创建更自然的动画效果:

PropertyAnimation {property: "rotation"to: 360easing.type: Easing.OutBounceeasing.amplitude: 2.0duration: 1000
}

相对值动画

PropertyAnimation支持相对当前值的动画:

PropertyAnimation {property: "x"to: myItem.x + 50  // 相对当前位置移动50像素duration: 500
}

多属性动画

可以同时对多个属性应用动画:

ParallelAnimation {PropertyAnimation { property: "x"; to: 100 }PropertyAnimation { property: "y"; to: 100 }PropertyAnimation { property: "opacity"; to: 0.5 }
}

PropertyAnimation的强大之处在于它的通用性,几乎可以对任何QML元素的任何属性进行动画处理,是构建动态UI的基础。

数字动画(NumberAnimation)

NumberAnimation是PropertyAnimation的派生类,专门用于处理数值类型的属性动画,如位置、大小、旋转角度等。

核心属性

NumberAnimation继承了PropertyAnimation的所有属性,并特别优化了对数值类型的处理:

属性类型描述默认值
fromreal动画起始值当前属性值
toreal动画结束值必须指定
byreal相对变化量-
其他属性继承自PropertyAnimation

基本用法示例

import QtQuick 2.0Rectangle {width: 100; height: 100color: "red"// 数字动画作为属性值源NumberAnimation on x {to: 50duration: 1000}
}

三种写法对比

NumberAnimation有三种主要使用方式:

方法1:直接绑定属性

NumberAnimation on rotation {id: minutePinAnifrom: 0to: 360duration: 20000loops: Animation.Infinite
}

方法2:独立动画对象

NumberAnimation {id: minutePinAnitarget: minPinproperty: "rotation"to: 360duration: 10000loops: Animation.Infinite
}

方法3:通过Behavior

Behavior on rotation {NumberAnimation {from: 0to: 100duration: 20000loops: Animation.Infinite}
}

与RotationAnimation的区别

虽然NumberAnimation可以用于旋转动画,但QML提供了专门的RotationAnimation类型,它比NumberAnimation多了一个旋转方向属性:

RotationAnimation {target: itemproperty: "rotation"direction: RotationAnimation.Clockwise // 顺时针方向from: 0to: 360duration: 1000
}

RotationAnimation的direction属性可以是:

  • RotationAnimation.Numerical (默认):数值线性插值
  • RotationAnimation.Clockwise:顺时针旋转
  • RotationAnimation.Counterclockwise:逆时针旋转
  • RotationAnimation.Shortest:沿最短路径旋转

NumberAnimation因其简单高效,在大多数数值动画场景中都是首选方案,特别是当需要精确控制数值变化过程时。

预定义的目标和属性动画

QML提供了一种更简洁的语法来定义属性动画,即直接在属性上声明动画,这种方式称为"预定义的目标和属性动画"或"on语法"。

基本语法

<AnimationType> on <property> {// 动画属性设置
}

典型示例

import QtQuick 2.0Rectangle {id: rectwidth: 100; height: 100color: "red"// 预定义x属性的动画PropertyAnimation on x {to: 100duration: 500}// 预定义y属性的动画PropertyAnimation on y {to: 100duration: 500}
}

特点与优势

  1. 简洁性​:不需要指定target和property,代码更简洁
  2. 自动绑定​:动画自动绑定到声明它的元素的对应属性
  3. 自动运行​:这种形式的动画会在组件加载完成后自动开始运行
  4. 适用于任何属性​:可以对任何支持动画的属性使用此语法

实际应用案例

import QtQuick 2.15Rectangle {width: 200height: 200anchors.centerIn:  parentcolor: "lightgreen"// 旋转动画RotationAnimation on rotation {from: 0to: 360duration: 2000loops: Animation.Infinite}// 缩放动画ScaleAnimator on scale {from: 0.5to: 1.5duration: 1000loops: Animation.Infinite}// 透明度动画OpacityAnimator on opacity {from: 0.3to: 1.0duration: 1500loops: Animation.Infinite}}

与独立动画的对比

相比于独立的动画声明,预定义语法有以下区别:

特性预定义语法独立动画
目标对象隐含(父元素)需显式指定
属性绑定自动关联需显式指定
执行时机自动开始需手动启动或设置running
复用性较低较高
代码量较少较多

预定义的目标和属性动画语法非常适合那些简单、直接的动画需求,特别是在原型设计或简单动画场景中,可以显著减少代码量并提高可读性。

过渡动画(Transition)

Transition用于定义状态变化时的动画效果,它可以在元素从一个状态切换到另一个状态时,自动应用指定的动画。

核心属性

Transition的主要属性如下:

属性类型描述默认值
fromstring起始状态名"" (任何状态)
tostring目标状态名"" (任何状态)
reversiblebool是否可反向播放false
enabledbool是否启用过渡true
animationslist动画列表空列表

基本用法

import QtQuick 2.15Rectangle {id: myRectwidth: 100; height: 100color: "red"state: "state1"MouseArea {anchors.fill: parentonPressed: myRect.state = "state2"onReleased: myRect.state = "state1"}states: [State {name: "state1"PropertyChanges { target: myRect; x: 0; y: 0 }},State {name: "state2"PropertyChanges { target: myRect; x: 100; y: 100 }}]transitions: [Transition {from: "state1"to: "state2"NumberAnimation { properties: "x,y"; duration: 500 }},Transition {from: "state2"to: "state1"NumberAnimation { properties: "x,y"; duration: 300 }}]}

 

多属性过渡示例

transitions: Transition {// 颜色过渡ColorAnimation { duration: 1000 }// 位置过渡NumberAnimation { properties: "x,y"duration: 500 easing.type: Easing.OutBack}// 旋转过渡RotationAnimation { duration: 700 direction: RotationAnimation.Clockwise}
}

高级用法:条件过渡

可以根据不同条件应用不同的过渡效果:

transitions: [Transition {from: "*"; to: "dragging"NumberAnimation { property: "scale"; to: 1.2; duration: 200 }},Transition {from: "dragging"; to: "*"SequentialAnimation {NumberAnimation { property: "scale"; to: 1.0; duration: 200 }SpringAnimation { property: "rotation"; spring: 2; damping: 0.2 }}}
]

与Behavior的区别

Transition和Behavior都用于属性变化时的动画,但有以下区别:

特性TransitionBehavior
触发条件状态变化任何属性变化
作用范围状态切换期间始终有效
控制粒度基于状态基于属性
适用场景明确的状态机持续性的属性变化

Transition在创建有明确状态划分的界面时非常有用,如折叠/展开、激活/非激活等场景,能够提供清晰的视觉反馈和状态转换指示。

默认行为动画(Behavior)

Behavior是QML中用于对属性值变化做隐式动画的机制,它绑定到某个属性上,当该属性在运行时被修改时,会自动触发预定义的动画效果

核心属性

Behavior的主要属性如下:

属性类型描述默认值
animationAnimation属性变化时应用的动画必须指定
enabledbool是否启用行为动画true

基本语法

Behavior on <property> {<animation>
}

基础示例

import QtQuick 2.15Rectangle {width: 100; height: 100color: "red"// 为x坐标变化添加行为动画Behavior on x {NumberAnimation { duration: 500 }}MouseArea {anchors.fill: parentonClicked: parent.x = parent.x + 50}
}

常见内置Animation类型

Behavior可以与多种动画类型配合使用:

类型可动画化属性说明
NumberAnimation数值型(x, y, width...)通过线性或缓动曲线插值数值
ColorAnimationcolor, border.color...在两个颜色值之间渐变
RotationAnimationrotation对旋转角度做插值动画
ScaleAnimationscale对缩放因子做插值
SpringAnimation任意数值型弹簧阻尼动画,带回弹效果
SmoothedAnimation任意数值型平滑快速跟随目标值

组合多个动画

Behavior内部可以使用组合动画实现复杂效果:

Behavior on width {SequentialAnimation {NumberAnimation { duration: 300; easing.type: Easing.OutQuad }PauseAnimation { duration: 100 }NumberAnimation { duration: 200; easing.type: Easing.InQuad }}
}

条件性行为

可以动态启用或禁用Behavior:

Rectangle {id: rectproperty bool animationsEnabled: trueBehavior on x {enabled: rect.animationsEnabledNumberAnimation { duration: 200 }}
}

注意事项

  1. 初始化赋值不会触发​:组件创建时的初始设定不会触发Behavior动画
  2. 性能考虑​:不要对大量快速变化的属性绑定耗时动画
  3. 多重Behavior​:一个属性只能有一个Behavior,但可以在内部使用ParallelAnimation/SequentialAnimation
  4. 与visible属性​:对visible属性直接应用Behavior无效,可以改为对opacity应用动画然后绑定visible到opacity > 0

Behavior的主要优势在于它能够降低动画调用成本,无需在每次更改时手动启动动画,只需在组件声明里一次性配置,后续所有对该属性的改变都会平滑地过渡。

并行动画与序列动画(ParallelAnimation和SequentialAnimation)

QML提供了两种组合动画的方式:ParallelAnimation(并行动画)和SequentialAnimation(序列动画),它们作为容器可以嵌套其他动画元素,实现复杂的动画效果。

ParallelAnimation(并行动画)

ParallelAnimation允许所有子动画同时运行,适用于需要多个属性同步动画的场景。

核心属性
属性类型描述默认值
animationslist子动画列表空列表
runningbool是否运行false
loopsint循环次数1
alwaysRunToEndbool停止时是否完成当前动画false
基本示例
import QtQuick 2.15Rectangle {id: rectwidth: 100; height: 100color: "red"x: 0; y: 0; opacity: 1.0ParallelAnimation {running: trueNumberAnimation { target: rect; property: "x"; to: 200; duration: 1000 }NumberAnimation { target: rect; property: "y"; to: 200; duration: 1500 }PropertyAnimation { target: rect; property: "opacity"; to: 0.5; duration: 800 }}
}
动态添加动画

ParallelAnimation支持动态添加子动画:

ParallelAnimation {id: dynamicAnim
}function addScaleAnimation() {var anim = Qt.createQmlObject('import QtQuick 2.15; NumberAnimation { property: "scale"; to: 2.0; duration: 500 }', dynamicAnim);dynamicAnim.addAnimation(anim);
}

SequentialAnimation(序列动画)

SequentialAnimation按顺序依次运行子动画,适用于需要多个动画按特定顺序执行的场景。

核心属性
属性类型描述默认值
animationslist子动画列表空列表
runningbool是否运行false
loopsint循环次数1
alwaysRunToEndbool停止时是否完成当前动画false
currentAnimationAnimation当前正在运行的子动画null
基本示例
import QtQuick 2.15Rectangle {id: rectwidth: 100; height: 100color: "red"x: 0; y: 0SequentialAnimation {running: trueNumberAnimation { target: rect; property: "y"; to: 200; duration: 1000 }ColorAnimation { target: rect; property: "color"; to: "blue"; duration: 500 }RotationAnimation { target: rect; property: "rotation"; to: 360; duration: 800 }}
}
组合动画序列

可以嵌套ParallelAnimation和SequentialAnimation创建复杂动画:

SequentialAnimation {// 第一阶段:并行移动和旋转ParallelAnimation {NumberAnimation { property: "x"; to: 200 }RotationAnimation { target: rotation; to: 90 }}// 第二阶段:并行改变颜色和大小ParallelAnimation {ColorAnimation { property: "color"; to: "blue" }NumberAnimation { property: "width"; to: 150 }}// 第三阶段:暂停后恢复PauseAnimation { duration: 500 }NumberAnimation { property: "scale"; to: 1.0; duration: 300 }
}

注意事项

  1. 动画控制​:子动画的running属性会被容器动画控制,不应单独设置
  2. 持续时间​:ParallelAnimation的持续时间等于最长子动画的持续时间
  3. 性能考虑​:复杂的动画组合可能需要更多的CPU资源
  4. 调试技巧​:可以在动画的running和completed信号中添加console.log跟踪动画状态

ParallelAnimation和SequentialAnimation为QML动画提供了强大的组合能力,通过它们的嵌套和组合,可以构建出几乎任何复杂的动画序列,满足现代UI对动画效果的各类需求。

动画师动画(Animator)

Animator是Qt Quick 2.2及以上版本引入的一种特殊动画类型,与常规动画不同,Animator直接在Qt Quick的场景图渲染线程中执行,即使在UI线程繁忙时也能保持流畅的动画效果。

核心优势

  1. 独立于UI线程​:在UI线程阻塞时仍能流畅运行
  2. 高性能​:直接在渲染线程执行,减少中间步骤
  3. 专有类型​:针对特定属性优化的动画类型
  4. 简单易用​:语法与PropertyAnimation类似

Animator类型

QML提供了多种专门的Animator类型:

类型作用属性描述
XAnimatorx水平位置动画
YAnimatory垂直位置动画
ScaleAnimatorscale缩放动画
RotationAnimatorrotation旋转动画
OpacityAnimatoropacity透明度动画
UniformAnimatoruniform着色器统一变量动画

基本用法

import QtQuick Rectangle {id: rect1width: 100height: 100x: 10y: 10color: "red"XAnimator on x {from: 10to: 300duration: 2000loops: Animator.Infinite}YAnimator on y {from: 10to: 300duration: 2000loops: Animator.Infinite}ScaleAnimator on scale {from: 0.1to: 1.5duration: 2000loops: Animator.Infinite}OpacityAnimator on opacity {from: 0.1to: 1.0duration: 2000loops: Animator.Infinite}RotationAnimator on rotation {from: 0to: 360duration: 2000loops: Animator.Infinite}}

与PropertyAnimation的对比

特性AnimatorPropertyAnimation
执行线程渲染线程UI线程
UI阻塞时继续运行可能卡顿
适用版本Qt Quick 2.2+所有版本
性能更高一般
属性支持特定属性所有属性
适用场景高性能需求通用需求

Animator类型特别适合那些需要高性能、流畅动画的场景,特别是在UI线程可能有繁重任务时,使用Animator可以确保动画不受影响,保持流畅运行。

精灵动画(SpriteAnimations)--嵌入式使用较少,了解就好

精灵动画是游戏开发和交互式应用中常见的技术,通过快速连续显示一系列图像帧来创建动画效果。QML提供了SpriteSequence和Sprite元素来实现精灵动画。

核心组件

  1. SpriteSequence​:精灵动画的容器,管理多个Sprite动画
  2. Sprite​:定义单个动画序列
  3. AnimatedSprite​:简化版的单动画精灵(后面详细介绍)

SpriteSequence属性

属性类型描述默认值
currentSpritestring当前精灵动画的名称""
goalSpritestring目标精灵动画""
interpolatebool是否开启插值运算true
runningbool是否执行动画true
spriteslist精灵动画集合空列表

Sprite属性

属性类型描述
namestring动画名称
sourceurl精灵图片源
frameXint起始帧的x坐标
frameYint起始帧的y坐标
frameCountint动画帧数
frameWidthint单帧宽度
frameHeightint单帧高度
frameDurationint每帧持续时间(ms)
tomap过渡到其他动画的名称和权重

基本示例

import QtQuickWindow {width: 640height: 900visible: truetitle: qsTr("Hello World")MouseArea {anchors.fill: parentonClicked: {animation.start()}}SequentialAnimation {id: animation//脚本会在前一个动画结束后、下一个动画开始前执行//goalSprite属性可以指定目标Sprite类型,指定该属性后会无视过渡权重,而以最短的路径到达目标动画。即从still->blink->floating->flailing->falling这个顺序播放动画ScriptAction {script: image.goalSprite = "falling";}NumberAnimation {target: imageproperty: "y"to: 500duration: 12000}// 下降完成之后回到still动画ScriptAction {script: {image.goalSprite = "";image.jumpTo("still")}}PropertyAction {target: imageproperty: "y"value: 0}}//精灵动画的容器,管理多个Sprite动画SpriteSequence {id: imagewidth: 256height: 256anchors.horizontalCenter: parent.horizontalCenterinterpolate: falsegoalSprite: "" //最终动画// 权重的作用原理​// ​数值含义​:to对象中的键值对(如"still":1)表示从当前动画切换到其他动画的相对概率。// 例如,"still":1, "blink":0.1表示:// 切换到still动画的概率是 1/(1+0.1) ≈ 90.9%// 切换到blink动画的概率是 0.1/(1+0.1) ≈ 9.1%// ​权重为0​:如"floating":0表示禁止切换到该动画// ​行为表现​:动画播放时,系统会按权重比例随机选择下一状态,still动画有极高概率保持,偶尔触发blink,而不会切换到floating// 静止Sprite {name: "still"source: "BearSheet.png"frameCount: 1  //帧数frameWidth: 256 //帧的宽度和高度frameHeight: 256frameDuration: 100 //持续时间to: {"still": 1,  //1代表权重"blink": 0.1,"floating": 0}}// 眨眼Sprite {name: "blink"source: "BearSheet.png"frameCount: 3frameX: 256frameY: 1536frameWidth: 256frameHeight: 256frameDuration: 100to: {"still": 1}}// 漂浮Sprite {name: "floating"source: "BearSheet.png"frameCount: 9frameX: 0frameY: 0frameWidth: 256frameHeight: 256frameDuration: 160to: {"still": 0,"flailing": 1}}// 摆动Sprite {name: "flailing"source: "BearSheet.png"frameCount: 8frameX: 0frameY: 768frameWidth: 256frameHeight: 256frameDuration: 160to: {"falling": 1}}// 下降Sprite {name: "falling"source: "BearSheet.png"frameCount: 5frameY: 1280frameWidth: 256frameHeight: 256frameDuration: 160to: {"falling": 1}}}
}

效果:

动画过渡机制

SpriteSequence中的动画可以通过to属性定义状态转换:

  1. 随机转换​:根据权重随机切换到其他动画
  2. 强制转换​:通过设置goalSprite强制切换到指定动画
  3. 直接跳转​:使用jumpTo()方法立即切换到指定动画

使用场景

  1. 游戏角色动画(行走、奔跑、跳跃等)
  2. 复杂的状态转换动画
  3. 需要随机或条件触发动画变化的场景
  4. 基于精灵图的动画效果

精灵动画特别适合游戏开发和需要复杂动画序列的应用,它能够有效地组织和管理多个动画状态,并通过状态转换创建丰富的交互体验。

动态精灵动画(AnimatedSprite)--嵌入式使用较少,了解就好

AnimatedSprite是QML中用于实现帧动画的简化组件,适用于不需要复杂状态管理的单一动画序列。

核心属性

AnimatedSprite的主要属性如下:

属性类型描述默认值
frameCountint动画总帧数1
frameRatereal每秒播放帧数-
frameWidthint单帧图像宽度元素宽度
frameHeightint单帧图像高度元素高度
sourceurl精灵图集路径必须指定
loopsint循环次数Animation.Infinite
currentFrameint当前帧索引0
frameDurationint每帧持续时间(ms)-
frameSyncbool是否同步显示刷新率false
interpolatebool是否在帧间插值true
pausedbool是否暂停false
reversebool是否反向播放false
runningbool是否运行true

基本用法

import QtQuick 2.12
import QtQuick.Window 2.12Window {visible: truewidth: 800height: 600color: "black"title: "Qt基于Qml图像帧动画播放"AnimatedSprite {id: animatedwidth: 365height: 365anchors.centerIn: parentsource: "qrc:/numbers.png"frameWidth: 64frameHeight: 64frameDuration: 1000 // 每秒播放一帧frameCount: 10frameX: 0frameY: 0onCurrentFrameChanged: {info.text = "%1/%2".arg(animated.currentFrame).arg(animated.frameCount)}}// 控制界面Row {spacing: 20anchors.horizontalCenter: parent.horizontalCenteranchors.bottom: parent.bottomanchors.bottomMargin: 4Text {id: infowidth: 120height: 60color: "red"font.pixelSize: 38verticalAlignment: Text.AlignVCenterhorizontalAlignment: Text.AlignRight}Button {width: 120height: 60text: (animated.paused === true) ? "播放" : "暂停"onClicked: (animated.paused === true) ? animated.resume() : animated.pause()}Button {width: 120height: 60text: "单帧播放"onClicked: animated.advance()}Button {width: 120height: 60text: "重置"onClicked: animated.restart()}}
}

与SpriteSequence的对比

特性AnimatedSpriteSpriteSequence
复杂度简单复杂
动画数量单一动画多动画序列
状态转换不支持支持
性能更高略低
适用场景简单帧动画复杂动画状态机

​性能优化建议

  1. 使用精灵图集​:将多帧打包到一个图像文件中,减少资源加载开销
  2. 合理设置帧率​:根据实际需要设置,避免不必要的渲染
  3. 适时暂停​:当动画不可见时暂停播放
  4. 预加载资源​:提前加载动画资源,避免运行时卡顿
  5. 减少插值​:对于像素艺术风格动画,关闭interpolate属性

AnimatedSprite因其简单易用和高效性能,成为实现简单帧动画的首选方案,特别适合游戏特效、加载动画、简单角色动画等场景。

弹动效果(Flickable)

Flickable是Qt Quick中用于实现可拖动和弹动效果的元素,它提供了一个可以滚动的区域,用户可以通过滑动手势浏览超出显示区域的内容。

核心属性

Flickable的主要属性如下:

属性类型描述默认值
contentWidthreal内容宽度必须指定
contentHeightreal内容高度必须指定
contentXreal当前水平位置0
contentYreal当前垂直位置0
flickableDirectionenum滑动方向(Flickable.AutoFlickDirection等)AutoFlickDirection
boundsBehaviorenum边界行为(Flickable.StopAtBounds等)StopAtBounds
maximumFlickVelocityreal最大滑动速度(像素/秒)平台相关
flickDecelerationreal滑动减速度平台相关
interactivebool是否允许用户交互true
pixelAlignedbool是否像素对齐false
pressDelayint按下延迟时间(ms)0

基本用法

import QtQuick 2.5
import QtQuick.Window 2.2Window {visible: truewidth: 640height: 480title: qsTr("Flickable Demo")Flickable {id: flickableinteractive: trueanchors.fill: parentcontentWidth: 1000contentHeight: 1000boundsBehavior: Flickable.StopAtBounds// 内容项 - 一个大图像Image {id: imagesource: "kun.jpg"width: 1000height: 1000}}// 添加滚动条指示ScrollBar {id: vbarwidth: 12height: flickable.heightanchors.right: flickable.rightorientation: Qt.Verticalposition: flickable.visibleArea.yPositionsize : flickable.visibleArea.heightRatioonPositionChanged: {if (active) flickable.contentY = position * (flickable.contentHeight );}}ScrollBar {id: hbarwidth: flickable.widthheight: 12anchors.bottom: flickable.bottomorientation: Qt.Horizontalposition: flickable.visibleArea.xPositionsize : flickable.visibleArea.widthRatioonPositionChanged: {if (active) flickable.contentX = position * (flickable.contentWidth );}}
}

动态内容示例

Flickable常用于显示动态生成的内容:

Flickable {anchors.fill: parentcontentWidth: col.widthcontentHeight: col.heightColumn {id: colwidth: parent.widthRepeater {model: 50delegate: Rectangle {width: col.widthheight: 60color: index % 2 ? "lightgray" : "white"Text {text: "Item " + indexfont.pixelSize: 20anchors.centerIn: parent}}}}
}

高级用法:自定义回弹效果

Flickable的rebound属性允许开发者自定义内容回弹到边界时的过渡动画效果:

Flickable {width: 200; height: 200contentWidth: 400; contentHeight: 400boundsBehavior: Flickable.DragOverBoundsrebound: Transition {NumberAnimation {properties: "x,y"duration: 1000easing.type: Easing.OutBounce}}Rectangle {width: 400; height: 400gradient: Gradient {GradientStop { position: 0.0; color: "lightsteelblue" }GradientStop { position: 1.0; color: "blue" }}}
}

边界行为详解

Flickable提供了多种边界行为控制方式:

  1. StopAtBounds​(默认):内容不能拖动到边界之外,轻拂也不会超调
  2. DragOverBounds​:内容可以拖动到边界之外,但轻拂不会超调
  3. OvershootBounds​:轻拂时可以超过边界,但不能拖动到边界之外
  4. DragAndOvershootBounds​:内容可以拖动到边界之外,轻拂时也可以超过边界

性能优化技巧

  1. 设置clip属性​:对于非全屏Flickable,应将clip设为true以避免渲染开销
  2. 合理使用pixelAligned​:对于像素精确的内容,启用pixelAligned可避免亚像素渲染
  3. 动态加载内容​:对于超长列表,考虑使用动态加载技术
  4. 避免过度绘制​:优化内容项的绘制逻辑

翻转效果(Flipable)

Flipable是QML中用于实现3D翻转效果的元素,可以创建卡片翻转、面板切换等视觉效果。

核心属性
属性类型描述默认值
frontItem正面显示的项必须指定
backItem背面显示的项可选
sideenumeration当前显示的面(Front或Back)Front
transformlist应用的变换列表空列表
axisvector3d旋转轴(x,y,z)(0,1,0)
anglereal当前旋转角度(度)0

基本用法

import QtQuickWindow {width: 640height: 480visible: truetitle: qsTr("Hello World")Flipable {id: flipablewidth: 240height: 240anchors.centerIn: parentproperty bool flipped: falsedfront: Image {source: "front.png"anchors.centerIn: parent}back: Image {source: "back.png"anchors.centerIn: parent}transform: Rotation {id: rotationorigin.x: flipable.width / 2origin.y: flipable.height / 2axis.x: 0axis.y: 1axis.z: 0angle: 0}states: State {name: "back"when: flipable.flippedPropertyChanges {target: rotationangle: 180}}transitions: Transition {NumberAnimation {target: rotationproperty: "angle"duration: 500}}MouseArea {anchors.fill: parentonClicked: {flipable.flipped = !flipable.flipped}}}
}

 

性能优化建议

  1. 简化内容​:Flipable的两面内容应尽量简单,避免复杂嵌套
  2. 合理使用Perspective​:在父元素上设置Perspective变换可增强3D效果
  3. 避免频繁切换​:翻转动画较耗资源,不宜频繁触发
  4. 预渲染内容​:对于复杂内容,考虑使用ShaderEffect预渲染

总结

QML提供了丰富而强大的动画系统,从基础的属性动画到复杂的3D效果,开发者可以创建各种流畅的交互体验。关键要点包括:

  1. 选择合适的动画类型​:根据场景选择PropertyAnimation、Behavior或Animator
  2. 组合使用动画​:利用ParallelAnimation和SequentialAnimation创建复杂序列
  3. 性能优化​:对于频繁触发的动画,优先考虑Animator类型
  4. 状态管理​:合理使用State和Transition管理界面状态变化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89736.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LangGraph教程9:LangGraph检查点和Send机制

文章目录 检查点 send机制 检查点 检查点是每个超级步骤保存的图状态的快照,并由StateSnapshot对象表示,具有以下关键属性: config:与此检查点相关的配置。 metadata:与此检查点相关的元数据。 values:此时状态通道的值。 next:将要在图中执行的下一个节点名称的元组。…

面试高频题 力扣 130. 被围绕的区域 洪水灌溉(FloodFill) 深度优先遍历(dfs) 暴力搜索 C++解题思路 每日一题

目录零、题目描述一、为什么这道题值得你花时间掌握&#xff1f;二、题目拆解&#xff1a;提取核心关键点三、解题思路&#xff1a;从边界入手&#xff0c;反向标记四、算法实现&#xff1a;深度优先遍历&#xff08;DFS&#xff09; 两次遍历五、C代码实现&#xff1a;一步步拆…

QA:多品牌多架构私有云的数据备份及恢复有哪些最佳实践?

一、跨平台备份架构设计​1、统一管理平台选型选择支持多品牌接口的备份软件&#xff0c;通过抽象层适配不同私有云API。例如&#xff0c;备份软件可同时对接VMware、OpenStack、ZStack等平台&#xff0c;实现策略集中配置与任务调度。​2、数据抽象与格式标准化采用中间数据层…

LeetCode Hot100 【1.两数之和、2.两数相加、3.无重复字符的最长子串】

1. 两数之和 自己做 分析 解法1&#xff1a;暴力解 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {int num1 0; //下标int num2 0;vector<int> s; //保存结果for(vector<int>::iterator it1 nums.…

AI一键“瘦身”,拯救巨卡无比的图

有没有碰到过那种巨卡无比的AI&#xff08;Illustrator&#xff09;文件&#xff1f;从素材网站下的&#xff0c;或者自己“图像描摹”出来的&#xff0c;上面密密麻麻全是锚点&#xff0c;动一下卡半天&#xff01;我是在海外工作了10年的职业设计师&#xff5e;这些年最大的心…

MySQL基础教程:SELECT语句详解

MySQL基础教程&#xff1a;SELECT语句详解一、SQL概述1.1 SQL背景知识1.2 SQL语言排行榜1.3 SQL分类二、SQL语言的规则与规范2.1 基本规则2.2 大小写规范2.3 注释2.4 命名规则2.5 数据导入三、基本的SELECT语句3.0 最简单的SELECT3.1 SELECT...FROM3.2 列的别名3.3 去除重复行3…

云原生环境下的安全控制框架设计

在这个容器满天飞、微服务遍地跑的时代&#xff0c;安全问题就像打地鼠游戏一样&#xff0c;刚按下一个又冒出三个。今天我们来聊聊如何在云原生环境中构建一套靠谱的安全控制框架。 &#x1f4d6; 文章目录 引言&#xff1a;云原生时代的安全新挑战云原生安全面临的核心挑战安…

Python关于numpy的基础知识

一.首先先安装numpy windowsr 输入cmd 然后像我这样输入进去&#xff0c;加一句后面的https&#xff1a;.....可以放其他他的镜像地址比如 清华大学镜像源&#xff1a;Simple Index阿里云镜像源&#xff1a;Simple Index中国科学技术大学镜像源&#xff1a;Verifying - USTC …

生成式人工智能实战 | 自回归模型详解与实现

生成式人工智能实战 | 自回归模型详解与实现 0. 前言 1. 文本生成模型分析 2. 数据处理 2.1 数据预处理 2.2 创建训练数据批次 3. 模型构建与训练 3.1 构建 LSTM 模型 3.2 训练 LSTM 模型 4. 生成文本 4.1 通过预测下一个 token 生成文本 4.2 控制文本生成的创意性 0. 前言 本…

路由器SDH POS接口

SDH POS 可看作“用 SDH 光纤专线给路由器当超级宽带网线”。 1️⃣ 拆名字 SDH 同步数字体系&#xff08;Synchronous Digital Hierarchy&#xff09;&#xff0c;运营商的骨干光传输标准&#xff0c;颗粒 STM-1/4/16/64…&#xff08;155 M/622 M/2.5 G/10 G&#xff09;。P…

响应式单位rpx及搭配使用UI产品工具

&#x1f3a8;✨ 欢迎来到RPX与即时设计的前端探索之旅 &#x1f680;&#x1f4bb; 亲爱的开发者朋友们&#xff1a; &#x1f44b; 大家好&#xff01;很高兴能在CSDN这个技术分享的平台上与各位相遇&#xff01;&#x1f31f; 作为一名长期奋战在前端开发一线的工程师&#…

MC0463四大名著-水浒签到

码蹄集OJ-四大名著-水浒签到 一、题目背景 本问题以《水浒传》为故事经纬&#xff0c;讲述史进对数列数字奥秘的探索。小码妹向其讲解特殊数列求和规则&#xff0c;我们需依据规则&#xff0c;对给定长度 n 的数列&#xff0c;按奇偶分组方式计算奇数组和与偶数组和的运算结果…

前缀和 HASH

前缀和 & HASH 个人模板 560. 和为 K 的子数组 class Solution {public int subarraySum(int[] nums, int k) {// 滑动窗口前缀和int n nums.length;int[] prevSum new int[n 1];for (int i 1; i < n 1; i) {prevSum[i] prevSum[i - 1] nums[i - 1];}int ans …

周末总结(2024/07/19)

工作 人际关系核心实践&#xff1a; 要学会随时回应别人的善意&#xff0c;执行时间控制在5分钟以内 遇到接不住的话题时拉低自己&#xff0c;抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内&#xff0c;职场社交不要放在5min以外 职场的人际关系在面对利益冲突是直接质疑&am…

若依框架开启注册功能全流程指南

在若依&#xff08;RuoYi&#xff09;框架中&#xff0c;用户注册功能并非默认开启&#xff0c;需要通过后端配置、前端调整以及必要的角色分配设置来实现。本文将详细介绍开启注册功能的完整步骤&#xff0c;帮助开发者快速完成配置。一、后端配置&#xff1a;开启注册功能开关…

STM32单片机_3

第十章IIC通信协议规定, 起始之后主机必须先发送一个字节: 从机地址读写位, 进行寻址然后接收一下应答位, 然后再发送一个字节, 写入从机寄存器地址 之后就可以进行数据的收发了注意: 在 主机的接收应答的时候, 立刻释放SDA 然后这时候从机会立刻做出反应, 即拉低SDA, 也就是置…

SpringAI_Chat模型_DeepSeek模型--基础对话

一、前言 Spring AI 提供跨 AI 供应商&#xff08;如 OpenAI、Hugging Face 等&#xff09;的一致性 API, 通过分装的ChatModel或ChatClient即可轻松调动LLM进行流式或非流式对话。 本专栏主要围绕着通过OpenAI方式调用各种大语言模型展开学习&#xff08;因为95%以上模型都…

数据结构:字符串(Strings)

目录 第一性问题&#xff1a;计算机如何表示文字&#xff1f; ASCII&#xff1a;最早的字符编码标准&#xff08;美国人写的&#xff09; Unicode&#xff1a;解决全球语言的编码方案 字符&#xff08;Character&#xff09; ​编辑 为什么字符常量必须加上单引号 &#…

【vue-5】Vue 3 中的 v-model:双向数据绑定的全面指南

在 Vue 开发中&#xff0c;v-model 是实现表单输入和应用状态之间双向绑定的关键指令。Vue 3 对 v-model 进行了重大改进&#xff0c;使其更加灵活和强大。本文将深入探讨 Vue 3 中 v-model 的工作原理、新特性以及最佳实践。 1. v-model 基础 1.1 什么是 v-model v-model 是 V…

结合自身,制定一套明确的 Web3 学习路线和技术栈建议

目录 ✅ 一、结合自身&#xff0c;明确方向和目的 ✅ 二、技术路线和建议 &#x1f9ed; 技术路线图&#xff08;按阶段划分&#xff09; 第一阶段&#xff1a;巩固 Web3 基础&#xff08;1-2 周&#xff09; 第二阶段&#xff1a;NFT 平台开发实战&#xff08;4-6 周&…