qml基础使用教程
qml使用,基础知识点总结
1、qml语法
(1)import声明导入指定模块的版本
(2)每个qml文件必须有一个根元素(与HTML一致)
(3)属性使用name:value赋值
(4)只可以使用ID对其进行访问(根元素对象ID设置为id:root)
(5)元素可以嵌套
(6)信号:on+属性+Change
(7)=赋值,只有一次效果,之后销毁
2、属性(properties)
(1)基础元素对象(item element):
group(分组) | properties(属性) |
---|---|
geometry(几何) | x、y、width、height、z(堆叠次序)定义元素之间的重叠顺序 |
layouthandling(布局操作) | anchors、left、right、top、bottom、verticalcenter、horizontalcenter、margins(元素间距) |
key handliking(按键操作) | 附加属性key(按键)和keyNavigation(按键定位)、输入焦点(focus)后可使用 |
transformation(转换) | 缩放(scale)、rotate(旋转),通用的x,y,z属性列表转换(transform),旋转基点设置(transformOrigin) |
visual(可视化) | opacity(控制透明度)、visible(是否可见)、clip(裁剪控制边界)smooth(平滑,提高渲染质量) |
state definition(状态定义) | states(状态列表属性,提供元素当前所支持的状态列表,当前属性的改变可以使用transitions(转变)属性列表来定义状态转变动画) |
添加自定义属性:
property int name:value
property alias name:value
3、基本元素
可视化元素 --item(基础元素对象),
(1)rectangle(矩形)设置渐变色
注意:矩形框必须要有宽高,否者不可见
Rectangle {
id: rect1
x: 12; y: 12
width: 176; height: 96 、
gradient: Gradient {
GradientStop { position: 0.0; color: "lightsteelblue" }
GradientStop { position: 1.0; color: "slategray" }
}
border.color: "slategray"
}
(2)文本元素(text element)
注:文本对齐---horizontalAlignment与verticalAlignment属性、anchors(锚)
渲染效果---style和styleColor配置文字的外框效果、浮雕或凹陷
文本元素初始宽高由字体决定默认为0
Text {
text: "The quick brown fox"
color: "#303030"
font.family: "Ubuntu"
font.pixelSize: 28
//当文本过长是使用省略号表示(a.....b),或使用elide属性,该属性允许设置文本左边、右边或中间的省略位置。当不想要省略号时使用wrapMode属性(前提设置好宽高)
width: 40; height: 120
text: 'A very long text'
// '...' shall appear in the middle
elide: Text.ElideMiddle // red sunken text styling
style: Text.Sunken
styleColor: '#FF4444' // align text to the top
verticalAlignment: Text.AlignTop
// only sensible when no elide mode
// wrapMode: Text.WordWrap
}
(3)图像元素(image element)
注:source属性---加载图片资源
fillMode属性---控制元素对象的大小
PreserveAspectCrop---//图像元素使用preserveaspectCrop可以避免裁剪图像数据被渲染到图像边界外,默认裁剪是被禁用的
QQMLImageProvider---可以通过c++代码创建自己的图像提供器,允许动态创建图像并且使用线程加载
Image {
x: 112; y: 12
width: 48 height: 118/2
source: "assets/rocket.png"
fillMode: Image.PreserveAspectCrop
clip: true //打开裁剪
}
(4)鼠标区域元素(mousearea element)
注:输入处理与可视化显示分开,会使交互区域可以比显示的区域大很多
Rectangle {
id: rect1
x: 12; y: 12
width: 76; height: 96
color: "lightsteelblue"
MouseArea {
id: area
width: parent.width
height: parent.height
onClicked: rect2.visible = !rect2.visible
}
}
Rectangle {
id: rect2
x: 112; y: 12
width: 76; height: 96
border.color: "lightsteelblue"
border.width: 4
radius: 8 }
(5)组件(compontents)
注:一个组件可以是一个重复使用的元素
一个文件就是一个基础组件
自定义一个button.qml组件
Item {
id: root
width: 116
height: 26
property alias text: label.text
signal anyname
Rectangle{
color: "lightsteelblue"
border.color: "slategrey"
anchors.fill: parent
MouseArea{
anchors.fill: parent
onClicked: {
root.anyname()
//label.text = "asd"
}
}
Text {
id: label
text: qsTr("start111")
anchors.centerIn: parent
}
}
}
外部调用该文件
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Button{
id:button
x:12
y:12
text: "start"
onAnyname: {
status.text = "button clicked"
}
}
Text {
id: status
text: qsTr("waiting...")
x:12
y:76
width: 116
height: 26
horizontalAlignment: Text.AlignHCenter
}
}
(6)简单转换(simple transformations)
注:文档中元素的顺序很重要,后加入的会覆盖之前的
1、自定义一个qml文件,其中包含鼠标点击区域的图片
ClickableImage.qml
Image{
id:root
signal clicked//自定义一个输出信号属性(名字任意)
mouseArea{
anchors.fill:parent
onClicked:root.clicked()
}
}
2、将多个类似的转换操作写入同一个qml
transformation.qml --直接调用该文件即可
Item {
width: bg.width
height: bg.height
Image {
id: bg
source: "qrc:/Image/Frame.jpg"
}
MouseArea{
id:backgroundClicker
anchors.fill: parent
onClicked: {
rocket1.x = 20
rocket2.rotation = 0
rocket3.rotation = 0
rocket3.scale = 1.0
}
}
//包含鼠标区域的图像元素
ClickableImage {//图片1点击右移
id: rocket1
x:20;
y:100
source: "qrc:/Image/butterfly.png"
onClicked:{
x+= 5
}
}
ClickableImage {//点击旋转
id: rocket2
x:200;
y:100
source: "qrc:/Image/down.png"
smooth: true
onClicked:{
rotation += 5
}
}
ClickableImage {//旋转加缩放
id: rocket3
x:400;
y:100
source: "qrc:/Image/up.png"
smooth: true
onClicked:{
rotation += 5
scale -= 0.05
}
}
}
7、定位元素(positioning element)
定位器:
row
column
Grid(栅格):设置行列排列在栅格中,未设置行列自动计算
flow(流):必须指定宽或高,可以同属性直接设定,也可以使用anchors布局
layoutDirection(布局方向):控制子元素的加入顺序
spacing:控制元素间隔
repeater(重复元素):与定位器一起使用,类似for循环与迭代器模式
DarkSquare{
id:root
width: 252
height: 252
property variant colorArray: ["#00bde3","#67c111","ea7025"]
Grid{
anchors.fill: parent
anchors.margins: 8
spacing: 4
Repeater{
model: 16
Rectangle{
width: 56
height: 56
//JS数学函数 生成随机数0~2
property int colorIndex: Math.floor(Math.random()*3)
color:root.colorArray[colorIndex]
border.color: Qt.lighter(color)
Text {
text: qsTr("cell")+index
anchors.centerIn: parent
color: "#f0f0f0"
}
}
}
}
}
8、布局元素(layout items)
(1)元素填充它的父元素
注:
GreenSquare {
BlueSquare {
width: 12
anchors.fill: parent //填充
anchors.left: parent.left //元素左对齐父类左边
anchors.left: parent.right //元素左边对齐父类右边
anchors.horizontalCenter: parent.horizontalCenter //水平对齐
anchors.verticalCenter: parent.verticalCenter //垂直对齐
anchors.centerIn: parent //父类的中心对齐
anchors.top: parent.bottom //元素上边对齐父类下边
anchors.horizontalCenterOffset: -12 //左偏移12个像素
anchors.margins: 8 //边界距离
text: '(1)'
}
}
实现矩形框的拖动
---Rectangle.qml
Rectangle{
width: 12
height: 12
color: "#ea7025"
//使用Qt.lighter(color)指定基于填充色的边界高亮色
border.color: Qt.lighter(color)
Drag.active: dragArea.drag.active//需要绑定到mouseArea.drg.active
Drag.hotSpot.x: 10
Drag.hotSpot.y: 10
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
}
}
main.qml
DropArea{
x:75
y:75
width: 100
height: 100
Rectangle{
anchors.fill: parent
visible: parent.containsDrag//为true是显示
}
}
RedSquare{
width: 30
Text {
id: name1
text: qsTr("text123")
}
}
9、输入元素(input element)
(1)文本输入
--允许用户输入一行文本,支持使用正则表达式和输入掩码的模式设置
Rectangle{
width: 200
height: textdata.height + 8
color: "linen"
border.color: "black"
property alias text: input1.text
property alias inputdata: input1
TextInput{
id:input1
width: 96
focus: true
color: "black"
anchors.fill: parent
anchors.margins: 4
anchors.verticalCenter: parent.verticalCenter
Text {
id: textdata
text: qsTr("")
}
}
}
焦点区域(foucesscope):按下tab键可以在两个组件之间切换焦点
(2)文本编辑(TXT样式) – 多行
Rectangle{
id:frame
width: 300
height: 200
color: "#f0f0f0"
border.color: "red"
Flickable
{
id: flick
anchors.fill:parent
width: 300; height: 200;
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
clip: true
visible: true
function ensureVisible(r)
{
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
TextEdit
{
id: edit
text:"aaaa"
width: flick.width
height: edit.paintedHeight
focus: true
wrapMode: TextEdit.Wrap
selectByMouse: true
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
}
}
Rectangle
{
id: scrollbar
visible: true
anchors.right: flick.right
x: 350
y: 0
width: 10
height: flick.height
color: "white"
Rectangle {
id: button
x: 0
y: flick.visibleArea.yPosition * scrollbar.height
width: 10
height: flick.visibleArea.heightRatio * scrollbar.height;
color: "grey"
// 鼠标区域
MouseArea {
id: mouseArea
anchors.fill: button
drag.target: button
drag.axis: Drag.YAxis
drag.minimumY: 0
drag.maximumY: scrollbar.height - button.height// 拖动
onMouseYChanged: {
flick.contentY = button.y / scrollbar.height * flick.contentHeight
}
}
}
}
}
10、按键元素(key element)
DarkSquare {
width: 400; height: 200
GreenSquare {
id: square
x: 8; y: 8
}
focus: true
Keys.onLeftPressed: square.x -= 8
Keys.onRightPressed: square.x += 8
Keys.onUpPressed: square.y -= 8
Keys.onDownPressed: square.y += 8
Keys.onPressed: {
switch(event.key) {
case Qt.Key_Plus:
square.scale += 0.2
break;
case Qt.Key_Minus:
square.scale -= 0.2
break;
}
}
}
11、动态元素(fluid elements)
(1)动画(animations)
动画控制了属性的改变,每个元素都有大量属性
//平移和旋转图片
Image {
id: image1
source: "qrc:/Images/Frame.jpg"
Image {
id: image2
source: "qrc:/Images/Sunny.jpg"
NumberAnimation on x {
to:240
duration: 4000
loops: Animation.Infinite
}
RotationAnimation on rotation {
to:360
duration: 4000
loops: Animation.Infinite
}
}
}
(2)动画元素(animation elements)
基本动画:
PropertyAnimation(属性动画)- 使用属性值改变播放的动画
NumberAnimation(数字动画)- 使用数字改变播放的动画
ColorAnimation(颜色动画)- 使用颜色改变播放的动画
RotationAnimation(旋转动画)- 使用旋转改变播放的动画
特殊动画:
PauseAnimation(停止动画)- 运行暂停一个动画
SequentialAnimation(顺序动画)- 允许动画有序播放
ParallelAnimation(并行动画)- 允许动画同时播放
AnchorAnimation(锚定动画)- 使用锚定改变播放的动画
ParentAnimation(父元素动画)- 使用父对象改变播放的动画
SmotthedAnimation(平滑动画)- 跟踪一个平滑值播放的动画
SpringAnimation(弹簧动画)- 跟踪一个弹簧变换的值播放的动画
PathAnimation(路径动画)- 跟踪一个元素对象的路径的动画
Vector3dAnimation(3D容器动画)- 使用QVector3d值改变播放的动画
复杂动画:在播放一个动画时,改变某个属性或运行一个脚本
PropertyAction(属性动作)- 在播放动画时改变属性
ScriptAction(脚本动作)- 在播放动画时运行脚本
(3)应用动画
—属性动画 在元素完整加载后自动运行
—属性动作 当属性值改变时自动运行
—独立运行动画 使用start()函数明确指定运行 或 running属性被设置为true(比如通过属性绑定)
注:父几何对象依赖子几何对象,所以不能对父对象设置宽高等属性,会破坏子对象内的属性配置
ClickableImage.qml
//封装组件,将图片和文字组合在一起
Item {
id:root
width: container.width
height: container.height
property alias text: label.text
property alias source: image.source
signal clicked
Column{
id:container
Image {
id: image
//source: "qrc:/Images/mario.gif"//默认不加载任何数据,调用时写
}
Text {
id: label
//text:"aaa"
width: image.width
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
color: "red"
}
}
MouseArea{
anchors.fill: parent
onClicked: root.clicked()
}
}
main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
//方式一 普通
ClickableImageV1{
id:rocket1
x:40
y:200
source: "qrc:/Images/sunny.png"
text: "sunny"
NumberAnimation on y{
to:40
duration: 4000
}
}
//方式二 行为策略动画,时刻在变化
ClickableImageV1{
id:rocket2
x:152
y:200
source: "qrc:/Images/Luffy.png"
text: "luffy"
Behavior on y{
NumberAnimation {
duration: 4000
}
}
onClicked: y = 40+Math.random()*(205-40)
}
//方式三 独立动画策略,手动设置开始暂停,与书写位置无关
ClickableImageV1{
id:rocket3
x:265
y:200
source: "qrc:/Images/butterfly.png"
text: "butterfly"
//数字动画
NumberAnimation{
id:anim
target: rocket3//选择哪个几何
properties: "y"//选择方向
from: 205
to:40
duration: 4000
}
onClicked: anim.start()
}
//方式四 使用running属性
ClickableImageV1{
id:rocket4
x:350
y:200
source: "qrc:/Images/LuffyQ.png"
text: "luffyQ"
NumberAnimation{
id:anim2
target: rocket4
properties: "y"
from: 300
to:30
duration: 4000
running: area.pressed//当鼠标一直 点击时移动
}
MouseArea{
id:area
anchors.fill: parent
}
}
}
4)缓冲曲线(easing curves)
没看懂,待续!!!!!!!!!!!!!!!
5)动画分组(grouped animations)
//平行动画 -ParallerAnimation
ParallerAnimationV1.qml
Rectangle{
id:root
width: 300
height: 200
color: "green"
anchors.centerIn: parent
property int duration: 1000
ClickableImageV1{
id:rocket
x:20
y:120
source: "qrc:/Images/Luffy.png"
text: "luffy"
onClicked: anim.restart()
}
ParallelAnimation{//类似容器存贮各种动画元素
//向右上角滑动
id:anim
NumberAnimation{
target: rocket
properties: "y"
to:20
duration: root.duration
}
NumberAnimation{
target: rocket
properties: "x"
to:150
duration: root.duration
}
}
}
//连续动画 -sequentialanimation.qml
SequentialAnimationV1.qml
Rectangle{
id:root
width: 300
height: 200
color: "green"
anchors.centerIn: parent
property int duration: 1000
ClickableImageV1{
id:rocket
x:20
y:120
source: "qrc:/Images/Luffy.png"
text: "luffy"
onClicked: anim.restart()
}
//先向上运动20,再向右运动160
SequentialAnimation{//类似容器存贮各种动画元素
id:anim
NumberAnimation{
target: rocket
properties: "y"
to:20
duration: root.duration * 0.6
}
NumberAnimation{
target: rocket
properties: "x"
to:160
duration: root.duration * 0.4
}
}
}
//例子
ExampleAnimation.qml
Item {
id:root
width: 480
height: 300
property int duration: 3000
anchors.centerIn: parent
//添加背景
Rectangle{
id:sky
width: parent.width
height: 200
gradient: Gradient{
GradientStop{
position: 0.0; color:"#0080ff"
}
GradientStop{
position: 1.0; color:"#66ccff"
}
}
}
Rectangle{
id:ground
width: parent.width
anchors.top: sky.bottom
anchors.bottom: parent.bottom
gradient: Gradient{
GradientStop{
position: 0.0;color: "#00ff00"
}
GradientStop{
position: 1.0;color: "#00803f"
}
}
}
//添加运动的元素
Image {
id: ball
x:-20
y:190
source: "qrc:/Images/butterfly.png"
scale: 0.3
MouseArea{
anchors.fill: parent
onClicked: {
ball.x = -20
ball.y = 190
ball.rotation = 0
anim.restart()
}
}
}
//动画操作
ParallelAnimation{
id:anim
//连续动画
SequentialAnimation{
NumberAnimation{
target: ball
properties: "y"
to:20
duration: root.duration * 0.4
easing.type: Easing.OutCirc
}
NumberAnimation{
target: ball
properties: "y"
to:240
duration: root.duration * 0.6
easing.type: Easing.OutBounce
}
}
//X轴运动
NumberAnimation{
target: ball
properties: "x"
to:400
duration: root.duration
}
//旋转动作
RotationAnimation{
target: ball
properties: "rotation"
to:720
duration: root.duration * 1.1
}
}
}
(2)状态与过渡(states and transitions)
1)状态(states)
-需要与基础元素(item)的states序列属性连接,默认状态在初始化元素属性时定义,命名为“”
方式一:状态改变由分配一个元素新的状态属性名来完成
Item {
id: root
states: [
State {
name: "go"
PropertyChanges { ... }
},
State {
name: "stop"
PropertyChanges { ... }
}
]
}
方式二:使用状态的when属性,when属性能够被设置为一个表达式的结果,为true是状态被使用
Item {
id: root
states: [
...
]
Button {
id: goButton
...
onClicked: root.state = "go"
}
}
例:点击变换红绿灯
Rectangle{//外边框
id: outline
width:150
height:250
color: "yellow"
Rectangle {
id: light1
x: 25; y: 15
width: 100; height: width
radius: width/2
color: "black"
}
Rectangle {
id: light2
x: 25; y: 135
width: 100; height: width
radius: width/2
color: "black"
}
state: "stop"
states: [
State {
name: "stop"
PropertyChanges {
target: light1
color:"red"
}
},
State {
name: "go"
PropertyChanges {
target: light2
color:"green"
}
}
]
//绑定鼠标
MouseArea{
anchors.fill: parent
onClicked: parent.state = (parent.state === "stop"? "go" : "stop")
}
}
2)过渡
transitions: [//过渡,实现红到绿渐变
Transition {
from: "stop"; to: "go"
ColorAnimation { target: light1; properties: "color"; duration: 2000 }
ColorAnimation { target: light2; properties: "color"; duration: 2000 }
}
]
12、模型-视图-代理(model-view-delegate)
(1)基础模型(Basic Model)
概念:保证数据和可视化的分离
//简单使用
Column{
spacing: 2
//中继器
Repeater{
//model: 10
model: ["a","b","c","d"]
Rectangle{
width: 100
height: 20
radius: 3
color: "lightBlue"
Text {
anchors.centerIn: parent
text: index + ":" + modelData
}
}
}
}
//链表元素
Column{
spacing: 2
Repeater{
model: ListModel{
ListElement{name:"a"; surfaceColor:"gray"}
ListElement{name:"b"; surfaceColor:"yellow"}
ListElement{name:"c"; surfaceColor:"blue"}
ListElement{name:"d"; surfaceColor:"orange"}
}
Rectangle{
width: 100
height: 20
radius: 3
color: "lightBlue"
Text {
anchors.centerIn: parent
text: name
}
Rectangle{
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 2
width: 16
height: 16
radius: 8
border.color: "black"
border.width: 1
color: surfaceColor
}
}
}
}
(2)动态视图(Dynamic VIews)
1)链表视图
Rectangle {
width: 80
height: 300
color: "#f0f0f0"
ListView{//滚动区域,默认有延伸效果
anchors.fill: parent
anchors.margins: 20
clip: true
model: 100
//设置方向
orientation: ListView.Horizontal//滚动方向
layoutDirection: Qt.RightToLeft//数据排列方向
delegate: numberDelegate
spacing: 5
//boundsBehavior: Flickable.StopAtBounds//禁止拖动到头后的延伸效果
//snapMode: ListView.SnapToItem//露出完整元素
//snapMode: ListView.SnapOneItem//鼠标松开后停止移动
}
Component{
id:numberDelegate
Rectangle{
width: 40
height: 40
color: "lightGreen"
Text {
id: name
anchors.centerIn: parent
font.pixelSize: 10
text: index
}
}
}
}
2)按键和高亮
Rectangle {
width: 240
height: 300
color: "#f0f0f0"
ListView{
anchors.fill: parent
anchors.margins: 20
clip: true
model: 100
delegate: numberDelegate
spacing: 5
//高亮和键盘
highlight: hightlightComponent
focus: true
}
Component{
id:hightlightComponent
//效果一
// Rectangle{
// width: ListView.view.width
// color: "lightGreen"
// }
//效果二 淡入淡出
Item {
width: ListView.view.width
height: ListView.view.currentItem.height
y:ListView.view.currentItem.y
Behavior on y{
SequentialAnimation{
PropertyAnimation { target: highlightRectangle; property: "opacity"; to: 0; duration: 200 }
NumberAnimation { duration: 1 }
PropertyAnimation { target: highlightRectangle; property: "opacity"; to: 1; duration: 200 }
}
}
Rectangle{
id:highlightRectangle
anchors.fill: parent
color: "lightGreen"
}
}
}
Component{
id:numberDelegate
Item {
width: 40
height: 40
Text {
anchors.centerIn: parent
font.pixelSize: 10
text: index
}
}
}
}
3)页眉和页脚
—页眉页脚代理元素不遵循链表视图的间隔(spacing)属性,手动设置位置
Rectangle {
width: 80
height: 300
color: "white"
ListView{
anchors.fill: parent
anchors.margins: 20
clip: true
model: 40
spacing: 5
delegate: numberDelegate
header: headerComponent
footer: footerComponent
}
Component{
id:headerComponent
Rectangle{
width: 40
height: 20
color: "yellow"
}
}
Component{
id:footerComponent
Rectangle{
width: 40
height: 20
color: "red"
}
}
Component{
id:numberDelegate
Rectangle{
width: 40
height: 40
color: "lightGreen"
Text {
anchors.centerIn: parent
font.pixelSize: 10
text: index
}
}
}
}
4)网格视图(The GridView)
Rectangle {
width: 240
height: 300
color: "white"
GridView{
anchors.fill: parent
anchors.margins: 20
clip:true
model: 100
//二维元素,不依赖元素间隔和大小,需设置单元宽高
cellWidth: 45
cellHeight: 45
//方向
//flow: GridView.LeftToRight
//flow:GridView.TopToBottom
delegate: numberDelegate
}
Component{
id:numberDelegate
Rectangle{
width: 40
height: 40
color: "lightGreen"
Text {
anchors.centerIn: parent
font.pixelSize: 10
text: index
}
}
}
}
(3)代理(Delegate)
1)动画添加和移出元素(Animation Added and Removed Irems)
Rectangle {
width: 480
height: 300
color: "#f0f0f0"
//显示列表
ListModel{
id:theModel
ListElement{number:0}
ListElement{number:1}
ListElement{number:2}
ListElement{number:3}
ListElement{number:4}
ListElement{number:5}
ListElement{number:6}
ListElement{number:7}
ListElement{number:8}
ListElement{number:9}
}
//点击按钮
Rectangle{
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 20
property int count: 9
height: 40
color: "darkGreen"
Text {
anchors.centerIn: parent
text: "add item!"
}
MouseArea{
anchors.fill:parent
onClicked: {
theModel.append({"number":++parent.count})
}
}
}
//布局
GridView{
anchors.fill: parent
anchors.margins: 20
anchors.bottomMargin: 80
clip: true
model: theModel
cellWidth: 45
cellHeight: 45
delegate: numberDelegate
}
Component{
id:numberDelegate
Rectangle{
id:wrapper
width: 40
height: 40
color: "lightGreen"
Text {
anchors.centerIn: parent
font.pixelSize: 10
text: number
}
MouseArea{
anchors.fill: parent
onClicked: {
if(!wrapper.GridView.delayRemove)
theModel.remove(index)
}
}
//特效
GridView.onRemove:SequentialAnimation{
PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: true }
NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false }
}
GridView.onAdd: SequentialAnimation {
NumberAnimation { target: wrapper; property: "scale"; from: 0; to: 1; duration: 250; easing.type: Easing.InOutQuad }
}
}
}
}
2)形变的代理(Shape-Shifting Delegates)
//实现展开下拉框功能
Item {
width: 300
height: 300
ListView{
id:listView
anchors.fill: parent
delegate:detailsDelegate//视图
model:planets//模型
}
//数据
ListModel{
id:planets
ListElement{name:"butterfly";imageSource:"qrc:/Images/butterfly.png";facts:"hello"}
ListElement{name:"down";imageSource:"qrc:/Images/down.png";facts:"world"}
ListElement{name:"Luffy";imageSource:"qrc:/Images/Luffy.png";facts:"aaaaa"}
ListElement{name:"OnePiece";imageSource:"qrc:/Images/OnePiece.png";facts:"d"}
ListElement{name:"Sunny";imageSource:"qrc:/Images/Sunny.jpg";facts:"e"}
}
//显示
Component{
id:detailsDelegate
Rectangle {//整个背景框
id: wrapper
width: listView.width
height: 30
color: "green"
state:""
Rectangle{//每个元素的框
// anchors.left: parent.left
// anchors.right: parent.right
// anchors.top: parent.top
anchors.fill: parent
anchors.margins: 1
height: 30
color:"#99F5D6"
Text {//标题
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
text: name
}
}
Rectangle{//右侧图标
id:image
color: "#F5D899"
width: 26
height: 26
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 2
anchors.topMargin: 2
Image {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: imageSource
}
}
MouseArea{//点击上边框设置显示隐藏下拉框内数据
anchors.fill: parent
onClicked: {
//parent.state = "expanded"
parent.state = ((parent.state === "expanded") ? "" : "expanded")
}
}
Item {//下拉框内显示的内容
id: factsView
anchors.top: image.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
opacity: 0
Rectangle{
anchors.fill: parent
color: "#cccccc"
Text {
anchors.fill: parent
anchors.margins: 5
clip: true
font.pixelSize: 12
text: facts
}
}
}
Rectangle{//右侧按钮点击效果
id:closeButton
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: 2
anchors.topMargin: 2
width: 26
height: 26
color: "red"
opacity: 0
MouseArea{
anchors.fill: parent
onClicked: {wrapper.state = ""}
}
}
states: [//点击标题后改变效果
State {
name: "expanded"
PropertyChanges { target: wrapper; height: listView.height}
PropertyChanges { target: image; width: listView.width}
PropertyChanges { target: factsView; opacity: 1}
PropertyChanges { target: closeButton; opacity: 1}
PropertyChanges { target: wrapper.ListView.view }
}
]
transitions: [//特效过渡
Transition {
NumberAnimation{
duration: 200
properties: "height,width,anchors.rightMargin,anchor"
}
}
]
}
}
}
(4)高级用法(Advanced Techniques)
1)路径视图(The PathView) —没看懂!!!
Item {
id:root
width: 300
height: 300
PathView{
anchors.fill: parent
delegate:flipCardDelegate
model: 100
path: Path{//设置pathview内代理的滚动路径
startX: root.width / 2
startY: 0
PathAttribute{name:"itemZ"; value:0}//Z-value深度值
PathAttribute{name: "itemAngle";value:-90.0;}//旋转
PathAttribute{name: "itemScale";value:0.5}//缩放
PathLine{x: root.width/2;y: root.height*0.4;}
PathPercent {value: 0.48;}//确保中间元素居中,并给其他元素提供空间
PathLine{x: root.width/2;y: root.height*0.5;}
PathAttribute{name: "itemAngle";value: 0.0;}
PathAttribute{name: "itemScale";value: 1.0;}
PathAttribute{name: "itemZ";value: 100 }
PathLine{x: root.width/2;y: root.height*0.6;}
PathPercent{value: 0.52;}
PathLine{x: root.width/2;y:root.height;}
PathAttribute{name: "itemAngle";value:90.0;}
PathAttribute{name: "itemScale";value:0.5;}
PathAttribute{name: "itemZ";value:0}
}
pathItemCount: 16//显示 浓密度
preferredHighlightBegin:0.5
preferredHighlightEnd: 0.5
}
Component{
id:flipCardDelegate
Item {
id: wrapper
width: 64
height: 64
visible: PathView.onPath
scale: PathView.itemScale
z:PathView.itemZ
property variant rotX: PathView.itemAngle
transform: Rotation{axis{x:1;y:0;z:0} angle:wrapper.r}
Rectangle{
anchors.fill: parent
color: "lightGreen"
border.color: "black"
border.width: 3
}
Text {
anchors.centerIn: parent
font.pixelSize: 30
text: index
}
}
}
}
2)XML模型 —没看懂!!!
3)链表分段(List with Sections)
//根据需求将相同属性划分在一起,区分类别
//seciton.property和section.criteria必须安装
//seciton.property(定义哪些属性用于内容划分)
//section.criteria(属性ViewSection.FullString(默认)有清晰的分段,属性ViewSection.FirstCharacter以首字母划分)
Rectangle {
width: 300
height: 200
color: "#f0f0f0"
ListView{
anchors.fill: parent
anchors.margins: 20
clip: true
model: spaceMen
delegate: spaceMangDelegate
section.property: "nation"//定义哪些属性划分,确保同一属性放在一起
section.delegate: sectionDelegate//给段指定代理组件
}
Component{//二级标题显示
id:spaceMangDelegate
Item {
width: 260
height: 20
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 10
font.pixelSize: 12
text: name
}
}
}
Component{
id:sectionDelegate
Rectangle{
width: 260
height: 20
color: "lightGray"
Text {
anchors.centerIn: parent
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 10
font.pixelSize: 12
font.bold: true
text: section
}
}
}
ListModel {
id: spaceMen
ListElement {name:"Abdul Ahad Mohmand"; nation: "Afganistan"; }
ListElement { name: "Marcos Pontes"; nation: "Brazil"; }
ListElement { name: "Alexandar Panayotov Alexandrov"; nation: "Bulga" }
ListElement { name: "Georgi Ivanov"; nation: "Bulgaria"; }
ListElement { name: "Roberta Bondar"; nation: "Canada"; }
ListElement { name: "Marc Garneau"; nation: "Canada"; }
ListElement { name: "Chris Hadfield"; nation: "Canada"; }
ListElement { name: "Guy Laliberte"; nation: "Canada"; }
ListElement { name: "Steven MacLean"; nation: "Canada"; }
ListElement { name: "Julie Payette"; nation: "Canada"; }
ListElement { name: "Robert Thirsk"; nation: "Canada"; }
ListElement { name: "Bjarni Tryggvason"; nation: "Canada"; }
ListElement { name: "Dafydd Williams"; nation: "Canada"; }
}
}
4)性能协调(Tunning Performance)
一个模型视图的性能很大程度上依赖于代理的创建,如滚动条,使用cachebuffer属性优化。创建更多的代理也会牺牲流畅度,尽量减少代理中的JavaScript数量,使用动态加载元素
对于静态模型,一个Repeater可以被用作视图。它可以非常方便的使用行 (Row),列(Column),栅格(Grid),或者流(Flow)来创建用户界面
对于动态或者大的数据模型,使用ListView或者GridView更加适合。它们会在需要时 动态的创建代理,减少在场景下一次显示的元素的数量
13、画布元素(Canvas Element)
(1)demo
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
//矩形
Canvas{
id:root
width: 200
height: 200
/*
onPaint: {
var ctx = getContext("2d")//创建2D对象
ctx.lineWidth = 4
ctx.stroKeStyle = "blue"
ctx.fillStyle = "steelblue"
ctx.beginPath()//开始一个新的路径使用moveto设置起点
ctx.moveTo(50,50)//起始点
ctx.lineTo(150,50)//画线
ctx.lineTo(150,150)
ctx.lineTo(50,150)
ctx.closePath()//关闭路径
//调用fill或stroke函数才会创建路径
ctx.fill()//填充
ctx.stroke//使用样式
}
*/
//直线
onPaint: {
var ctx = getContext("2d")
ctx.strokeStyle = "red"
ctx.beginPath()
ctx.moveTo(50,50)
ctx.lineTo(150,150)
ctx.closePath()
ctx.stroke()
}
}
}
(2)便捷的接口(Convenient API)
//绘制矩形,不需要调用stroke 或fill
Canvas {
id:root
width: 120
height: 120
onPaint: {
var ctx = getContext("2d")
ctx.fillStyle = "green"
ctx.strokeStyle = "blue"
ctx.lineWidth = 4
ctx.fillRect(20,20,80,80)
ctx.clearRect(30,30,60,60)
ctx.strokeRect(20,20,40,40)
}
}
(3)渐变(Gradients)
//画布除使用颜色填充外,可以使用渐变(在画布坐标下定义,不是在绘制路径下定义)或图像
Canvas {
id:root
width: 120
height: 120
onPaint: {
var ctx = getContext("2d")
var gradient = ctx.createLinearGradient(100,0,100,200)
gradient.addColorStop(0,"blue")
gradient.addColorStop(0.5,"lightsteelblue")
ctx.fillStyle = gradient
ctx.fillRect(50,50,100,100)
}
}
(4)阴影(Shadows)
//阴影是一个区域的轮廓线使用偏移量,颜色,模糊实现
Canvas {
id:root
width: 400
height: 300
onPaint: {
var ctx = getContext("2d")
ctx.stroKeStyle = "red" //画笔样式
ctx.lineWidth = 10 //边框宽度
ctx.fillStyle = "steelblue" //背景填充颜色
ctx.fillRect(0,0,root.width,root.height)
ctx.strokeRect(0,0,root.width,root.height) //stroke属性只能控制自己的
ctx.shadowColor = "red" //阴影
ctx.shadowOffsetX = 2 //阴影偏移值
ctx.shadowOffsetY = 2
ctx.shadowBlur = 10 // 阴影模糊
ctx.font = "bold 50px Arial"
ctx.fillStyle = "green" //字体填充绿色
ctx.fillText("Earth",30,180) //填充方式
//ctx.strokeText("blue",30,220) //描边方式
//context.strokeText("123",30,260)
}
(5)图片(Images)
//裁剪图片
Canvas {
id:root
width: 1000
height: 800
onPaint: {
var ctx = getContext("2d")
ctx.drawImage("qrc:/Images/Luffy.png",10,10)
ctx.save()
ctx.strokeStyle = "red"
ctx.beginPath()
ctx.moveTo(10,10)
ctx.lineTo(355,10)
ctx.lineTo(335,355)
ctx.closePath()
ctx.translate(150,100)
ctx.clip()
ctx.drawImage("qrc:/Images/Luffy.png",10,10)
ctx.stroke()
ctx.restore()
}
Component.onCompleted: {
loadImage("qrc:/Images/Luffy.png")
}
}
(6)转换(Transformation)
//注:调出来了但不知道为什么???
Canvas {
id: root
width: 240; height: 240
onPaint: {
var ctx = getContext("2d")
ctx.strokeStyle = "blue"//画笔样式
ctx.lineWidth = 4//
ctx.beginPath()
ctx.strokeRect(20, 20, 40, 40)
ctx.translate(40,40)
ctx.stroke()
// draw path now rotated
ctx.strokeStyle = "green"
ctx.rotate(Math.PI/4)
ctx.strokeRect(-20, -20, 40, 40)
ctx.closePath()
ctx.stroke()
}
}
(7)组合模式(Composition Mode)
//没看懂!!!
Canvas {
id: root
width: 240; height: 240
//随机出一些圆形
// onPaint: {
// var ctx = getContext("2d")
// ctx.globalCompositeOperation = "xor"
// ctx.fillStyle = "#33a9ff"
// for(var i = 0; i < 10; i++)
// {
// ctx.beginPath()
// ctx.arc(Math.random()*400, Math.random()*200, 20, 0, 2*Math.PI)
// ctx.closePath()
// ctx.fill()
// }
// }
//不同模式生成矩形和圆形的组合
property var operation: [
'source-over', 'source-in', 'source-over',
'source-atop', 'destination-over', 'destination-in',
'destination-out', 'destination-atop', 'lighter',
'copy', 'xor', 'qt-clear', 'qt-destination',
'qt-multiply', 'qt-screen', 'qt-overlay',
'qt-darken','qt-lighten', 'qt-color-dodge',
'qt-color-burn','qt-hard-light','qt-soft-light',
'qt-difference','qt-exclusion'
]
onPaint:{
var ctx = getContext('2d')
for(var i=0; i<operation.length; i++)
{
var dx = Math.floor(i%6)*100
var dy = Math.floor(i/6)*100
ctx.save()
ctx.fillStyle = '#33a9ff'
ctx.fillRect(10+dx,10+dy,60,60)
// TODO: does not work yet
ctx.globalCompositeOperation = root.operation[i]
ctx.fillStyle = '#ff33a9'
ctx.globalAlpha = 0.75
ctx.beginPath()
ctx.arc(60+dx, 60+dy, 30, 0, 2*Math.PI)
ctx.closePath()
ctx.fill()
ctx.restore()
}
}
}
(8)像素缓冲(Pixels Buffer)
//没看懂!!!
//左边绘制圆形,点击画布后将内容存储为一个图片链接,在右侧显示该图片
Rectangle {
width: 240;
height: 120
Canvas {
id: canvas
x: 10; y: 10
width: 100;
height: 100
property real hue: 0.0
onPaint: {
var ctx = getContext("2d")
var x = 10 + Math.random(80)*80
var y = 10 + Math.random(80)*80
hue += Math.random()*0.1
if(hue > 1.0) { hue -= 1 }
ctx.globalAlpha = 0.7
ctx.fillStyle = Qt.hsla(hue, 0.5, 0.5, 1.0)
ctx.beginPath()
ctx.moveTo(x+5,y)
ctx.arc(x,y, x/10, 0, 360)
ctx.closePath()
ctx.fill()
}
MouseArea {
anchors.fill: parent
onClicked: {
var url = canvas.toDataURL('image/png')
print('image url=', url)
image.source = url
}
}
}
Image {
id: image
x: 130; y: 10
width: 100; height: 100
}
Timer {
interval: 1000
running: true
triggeredOnStart: true
repeat: true
onTriggered: canvas.requestPaint()
}
}
(9)画布绘制(Canvas Paint)
//绘图功能,没看懂!!!
(10)HTML5画布移植(Porting from HTML5 Canvas)
//没看懂!!!
14、粒子模拟(Particle Simulations)
(1)概念(Concept):基于模糊渲染
粒子系统(ParticleSystem)- 管理发射器之间的共享时间线。
发射器(Emitter)- 向系统中发射逻辑粒子。
粒子画笔(ParticlePainter)- 实现粒子可视化。
方向(Direction)- 已发射粒子的向量空间。
粒子组(ParticleGroup)- 每个粒子是一个粒子组的成员。
粒子控制器(Affector)- 控制已发射粒子
(2)简单的模拟(Simple Simulation)
//绑定所有元素到一个模拟的粒子系统
//一个向系统发射粒子的发射器
//一个ParticlePainter派生元素,用来实现粒子的可视化
Rectangle {
id:root
width: 480
height: 160
color: "#1f1f1f"
anchors.centerIn: parent
//一、定义粒子系统
ParticleSystem{
id:particleSystem
}
//二、元素发射器
Emitter{
id:emitter
anchors.fill: parent
system: particleSystem//进行粒子系统绑定
emitRate: 10//每秒发射10个
lifeSpan: 1000//每个粒子生命周期
lifeSpanVariation: 500//一个已发射粒子的生命周期
size: 16//一个粒子开始的大小16像素
endSize: 32//结束时像素
//Tracer { color: 'green' }//跟踪元素,不能用
}
//图像粒子
ImageParticle{
source: "qrc:/Images/butterfly.png"
system: particleSystem
}
}
(3)粒子参数(Particle Parameters)
//图像粒子
ImageParticle{
source: "qrc:/Images/butterfly.png"
system: particleSystem
color: "#ffffff"
colorVariation: 0.2//粒子颜色变化范围正负20%
rotation: 15//顺时针旋转15度
rotationVariation: 5//不同粒子+-5度
rotationVelocity: 45//每个粒子以每秒45度旋转
rotationVelocityVariation: 15//每个粒子旋转速度变化范围+-15度
entryEffect: ImageParticle.Scale//缩放效果
(4)粒子方向(Directed Particle)
Rectangle {
id:root
width: 480
height: 160
color: "#1f1f1f"
anchors.centerIn: parent
//一、定义粒子系统
ParticleSystem{
id:particleSystem
}
//二、元素发射器
Emitter{
id:emitter
anchors.fill: parent
system: particleSystem//进行粒子系统绑定
width: 1//宽高设置为1保证粒子都从一个方向发出
height: 1
lifeSpan: 6400//每个粒子生命周期
lifeSpanVariation: 400//一个已发射粒子的生命周期
size: 16//一个粒子开始的大小16像素
//效果一,抛物线
// velocity: AngleDirection{
// angle: -45//方向右上
// angleVariation: 0//角度变化范围+-15度
// magnitude: 100//梯度值
// //magnitudeVariation: 50
// }
// acceleration: AngleDirection{
// angle: 90//加速度向下
// magnitude: 25//加速度为速度的1/4
// }
//效果二,右飘
// velocity:PointDirection{
// x:100
// y:0
// xVariation: 0
// yVariation: 100/6
// }
//效果三
velocity: TargetDirection{
targetX: 100
targetY: 0
targetVariation: 100 / 6
magnitude: 100
}
}
//图像粒子
ImageParticle{
source: "qrc:/Images/butterfly.png"
system: particleSystem
color: "#ffffff"
colorVariation: 0.2//粒子颜色变化范围正负20%
rotation: 15//顺时针旋转15度
rotationVariation: 5//不同粒子+-5度
rotationVelocity: 45//每个粒子以每秒45度旋转
rotationVelocityVariation: 15//每个粒子旋转速度变化范围+-15度
entryEffect: ImageParticle.Scale//缩放效果
}
}
(5)粒子画笔(Particle Painter)
Rectangle {
id:root
width: 480
height: 160
color: "#1f1f1f"
anchors.centerIn: parent
//一、定义粒子系统
ParticleSystem{
id:particleSystem
}
Emitter{
id:emitter
anchors.fill: parent
system: particleSystem//进行粒子系统绑定
emitRate: 10//每秒发射10个
lifeSpan: 1000//每个粒子生命周期
lifeSpanVariation: 500//一个已发射粒子的生命周期
size: 16//一个粒子开始的大小16像素
endSize: 32//结束时像素
//Tracer { color: 'green' }//跟踪元素,不能用
}
ItemParticle{//基于粒子画笔的代理
id:particle
system: particleSystem
delegate: itemDelegate
}
Component{//自定义代理效果
id:itemDelegate
Rectangle{
id:container
width: 32*Math.ceil(Math.random()*3)
height: width
color: "white"
Image {
anchors.fill: parent
anchors.margins: 4
source: "qrc:/Images/butterfly.png"
}
}
}
}
(6)粒子控制(Affecting Particles)
//粒子由发射器发出,之后发射器就无法改变粒子,允许使用粒子控制器控制发射后的粒子参数
生命周期(Age)- 修改粒子的生命周期
吸引(Attractor)- 吸引粒子朝向指定点
摩擦(Friction)- 按当前粒子速度成正比减慢运动
重力(Gravity)- 设置一个角度的加速度
紊流(Turbulence)- 强制基于噪声图像方式的流动
漂移(Wander)- 随机变化的轨迹
组目标(GroupGoal)- 改变一组粒子群的状态
子粒子(SpriteGoal)- 改变一个子粒子的状
//生命周期
// Age{
// anchors.horizontalCenter: parent.horizontalCenter
// width: 240
// height: 120
// system: particleSystem
// advancePosition: true//达到1200毫秒后粒子再次在该位置出现
// lifeLeft: 1200.
// once: true
// //Tracer{}
// }
//吸引
// Attractor{
// anchors.horizontalCenter: parent.horizontalCenter
// width: 160
// height: 120
// system: particleSystem
// pointX: 0
// pointY: 0
// strength: 1.0
// }
//摩擦 --减慢粒子运动速度为25像素每秒
// Friction{
// anchors.horizontalCenter: parent.horizontalCenter
// width: 240
// height: 120
// system: particleSystem
// factor: 0.8
// threshold: 25
// }
//重力
// Gravity{
// width: 240
// height: 240
// system: particleSystem
// magnitude: 50//梯度值,变化的速度
// angle: 90
// }
//紊流 --混乱映射方向力的矢量,是一个噪声图像定义的
// Turbulence{
// anchors.horizontalCenter: parent.horizontalCenter
// width: 240
// height: 120
// system: particleSystem
// strength: 100//影响度
// }
//漂移
Wander{
anchors.horizontalCenter: parent.horizontalCenter
width: 240
height: 120
system: particleSystem
affectedParameter: Wander.Position
pace: 200
yVariance: 240
}
(7)粒子组(Particle Group)
//没看懂!!!
15、着色器效果(Shader Effect)
(1)OpenGL着色器(OpenGL Shader)
包括:
一个顶点着色器:接收顶点数据,并在程序最后赋值给gl_Position,顶点经裁剪、转换、和栅格化后作为图像输出
一个片段着色器:像素进入片段着色器,进一步操作后赋值给gl_FragColor
(2)着色器元素(Shader Element)
qt提供两个元素对着色器编程:ShaderEffectSource(将一个qml元素渲染为一个纹理再渲染该纹理)和ShaderEffect(自定义着色器,能应用自定义的着色器到矩形的几何形状,并且能够使用在着色器中操作资源)
Rectangle {
width: 480
height: 240
color: "#1e1e1e"
anchors.centerIn: parent
Row{
anchors.centerIn: parent
spacing: 20
Image {
id: sourceImage
width: 80
height: 80
visible: true
source: "qrc:/Images/Luffy.png"
}
ShaderEffect{
id:effect
width: 80
height: 80
property variant source: sourceImage
}
ShaderEffect{
id:effect2
width: 80
height: 80
property variant source: sourceImage
// uniform-在处理过程中不能够改变的值。
// attribute-连接外部数据
// varying-着色器之间的共享数据
// highp-高精度值
// lowp-低精度值
// mat4-4x4浮点数(float)矩阵
// vec2-包含两个浮点数的向量
// sampler2D-2D纹理
// float-浮点数
// qt_Matrix:model-view-projection(模型-视图-投影)矩阵
// qt_Vertex:当前顶点坐标
// qt_MultiTexCoord0:纹理坐标
// qt_TexCoord0:共享纹理坐标
//顶点着色器
vertexShader: "
uniform highp mat4 qt_Matrix;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 qt_TexCoord0;
void main() {
qt_TexCoord0 = qt_MultiTexCoord0;
gl_Position = qt_Matrix * qt_Vertex;
}"
//片段着色器 --接收纹理坐标(来自qml资源属性(source property))
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
void main() {
gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
}"
}
}
}
(3)片段着色器(Fragement Shader)
Rectangle {
id:root
width: 480
height: 240
color: "#f0f0f0"
anchors.centerIn: parent
Grid{
anchors.centerIn: parent
spacing: 20
rows:2
columns: 4
Image {
id: sourceImage
width: 80
height: 80
source: "qrc:/Images/Luffy.png"
}
//自定义着色器 --- 红色着色器
ShaderEffect{
id:effect1
width: 80
height: 80
property variant source: sourceImage
fragmentShader: "
uniform lowp float qt_Opacity;
void main(){
gl_FragColor = vec4(1.0,0.0,0.0,1.0) * qt_Opacity;
}"
}
//自定义着色器 --- 使用纹理的红色着色器
ShaderEffect{
id:effect2
width: 80
height: 80
property variant source: sourceImage
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
void main(){
gl_FragColor = texture2D(source,qt_TexCoord0) * vec4(1.0,0.0,0.0,1.0) * qt_Opacity;
}"
}
//自定义着色器 --- 红色通道属性
ShaderEffect{
id:effect3
width: 80
height: 80
property variant source: sourceImage
property real redChannel: 0.3
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
uniform lowp float redChannel;//从一个着色器中标记一个值到qml
void main(){
gl_FragColor = texture2D(source,qt_TexCoord0) * vec4(redChannel,1.0,1.0,1.0) * qt_Opacity;
}"
}
//自定义着色器 --- 红色通道的动画
ShaderEffect{
id:effect4
width: 80
height: 80
property variant source: sourceImage
property real redChannel: 0.3
NumberAnimation on redChannel {
from: 0.0;
to: 1.0;
loops: Animation.Infinite;
duration: 4000
}
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
uniform lowp float redChannel;
void main(){
gl_FragColor = texture2D(source,qt_TexCoord0) * vec4(redChannel,0.0,0.0,1.0) * qt_Opacity;
}"
}
}
}
(4)波浪效果(Wave Effect)
Rectangle {
width: 480
height: 240
color: "#f0f0f0"
anchors.centerIn: parent
Row{
anchors.centerIn: parent
spacing: 20
Image {
id: sourceImage
width: 200
height: 160
source: "qrc:/Images/Frame.jpg"
}
ShaderEffect{
width: 200
height: 160
property variant source: sourceImage
property real frequency: 8
property real amplitude: 0.1
property real time: 0.0
NumberAnimation on time{
from: 0
to:Math.PI * 2
duration: 3000
loops: Animation.Infinite
}
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform lowp float qt_Opacity;
uniform highp float frequency;
uniform highp float amplitude;
uniform highp float time;
void main() {
highp vec2 pulse = sin(time - frequency * qt_TexCoord0);
highp vec2 coord = qt_TexCoord0 + amplitude * vec2(pulse.x, -pulse.x);
gl_FragColor = texture2D(source, coord) * qt_Opacity;
}"
}
}
}
(5)顶点着色器(Vertex Shader)
//main.qml
Rectangle {
width: 480; height: 240
color: '#f0f0f0'
TheGenieEffect {
source: Image { source: 'qrc:/Images/Frame.jpg' }
MouseArea {
anchors.fill: parent
onClicked: parent.minimized = !parent.minimized
}
}
}
//TheGenieEffect.qml
ShaderEffect {
id: genieEffect
width: 160; height: width
anchors.centerIn: parent
property variant source
mesh: GridMesh { resolution: Qt.size(10, 10) }//增加顶点数量,动画平缓
property real minimize: 0.0
property real bend: 0.0
property bool minimized: false
property real side: 1.0
ParallelAnimation {
id: animMinimize
running: genieEffect.minimized
SequentialAnimation {
PauseAnimation { duration: 300 }
NumberAnimation {
target: genieEffect; property: 'minimize';
to: 1; duration: 700;
easing.type: Easing.InOutSine
}
PauseAnimation { duration: 1000 }
}
SequentialAnimation {
NumberAnimation {
target: genieEffect; property: 'bend'
to: 1; duration: 700;
easing.type: Easing.InOutSine
}
PauseAnimation { duration: 1300 }
}
}
ParallelAnimation {
id: animNormalize
running: !genieEffect.minimized
SequentialAnimation {
NumberAnimation {
target: genieEffect; property: 'minimize';
to: 0; duration: 700;
easing.type: Easing.InOutSine
}
PauseAnimation { duration: 1300 }
}
SequentialAnimation {
PauseAnimation { duration: 300 }
NumberAnimation {
target: genieEffect; property: 'bend'
to: 0; duration: 700;
easing.type: Easing.InOutSine }
PauseAnimation { duration: 1000 }
}
}
vertexShader: "
uniform highp mat4 qt_Matrix;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp float height;
uniform highp float width;
uniform highp float minimize;
uniform highp float bend;
uniform highp float side;
varying highp vec2 qt_TexCoord0;
void main() {
qt_TexCoord0 = qt_MultiTexCoord0;
highp vec4 pos = qt_Vertex;
pos.y = mix(qt_Vertex.y, height, minimize);
highp float t = pos.y / height;
t = (3.0 - 2.0 * t) * t * t;
pos.x = mix(qt_Vertex.x, side * width, t * bend);
gl_Position = qt_Matrix * pos;
}"
}
(6)剧幕效果(Curtain Effect)
//main.qml
Item {
id: root
width: background.width
height: background.height
Image {
id: background
anchors.centerIn: parent
source: "qrc:/Images/Luffy.png"
}
Text {
anchors.centerIn: parent
font.pixelSize: 48
color: "#efefef"
text: "Qt5 Cadaques"
}
TheCurtainEffect{
id:curtain
anchors.fill: parent
}
MouseArea{
anchors.fill: parent
onClicked: curtain.open = !curtain.open
}
}
//TheGenieEffect.qml
ShaderEffect {
id: genieEffect
width: 160; height: width
anchors.centerIn: parent
property variant source
mesh: GridMesh { resolution: Qt.size(10, 10) }//增加顶点数量,动画平缓
property real minimize: 0.0
property real bend: 0.0
property bool minimized: false
property real side: 1.0
ParallelAnimation {
id: animMinimize
running: genieEffect.minimized
SequentialAnimation {
PauseAnimation { duration: 300 }
NumberAnimation {
target: genieEffect; property: 'minimize';
to: 1; duration: 700;
easing.type: Easing.InOutSine
}
PauseAnimation { duration: 1000 }
}
SequentialAnimation {
NumberAnimation {
target: genieEffect; property: 'bend'
to: 1; duration: 700;
easing.type: Easing.InOutSine
}
PauseAnimation { duration: 1300 }
}
}
ParallelAnimation {
id: animNormalize
running: !genieEffect.minimized
SequentialAnimation {
NumberAnimation {
target: genieEffect; property: 'minimize';
to: 0; duration: 700;
easing.type: Easing.InOutSine
}
PauseAnimation { duration: 1300 }
}
SequentialAnimation {
PauseAnimation { duration: 300 }
NumberAnimation {
target: genieEffect; property: 'bend'
to: 0; duration: 700;
easing.type: Easing.InOutSine }
PauseAnimation { duration: 1000 }
}
}
vertexShader: "
uniform highp mat4 qt_Matrix;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp float height;
uniform highp float width;
uniform highp float minimize;
uniform highp float bend;
uniform highp float side;
varying highp vec2 qt_TexCoord0;
void main() {
qt_TexCoord0 = qt_MultiTexCoord0;
highp vec4 pos = qt_Vertex;
pos.y = mix(qt_Vertex.y, height, minimize);
highp float t = pos.y / height;
t = (3.0 - 2.0 * t) * t * t;
pos.x = mix(qt_Vertex.x, side * width, t * bend);
gl_Position = qt_Matrix * pos;
}"
}
(7)图像效果库(Qt GraphicsEffect Library)
//快速模糊demo
import QtQuick 2.0
import QtGraphicalEffects 1.0
Rectangle {
width: 480
height: 240
color: "#f0f0f0"
Row{
anchors.centerIn: parent
spacing: 16
Image {
id: sourceImage
source: "qrc:/Images/Frame.jpg"
width: 200
height: 200
sourceSize: Qt.size(parent.width,parent.height)
smooth: ture
}
FastBlur{
width: 200
height: 200
source: sourceImage
radius: blurred?32:0
property bool blurred: false
Behavior on radius{
NumberAnimation { duration: 1000 }
}
MouseArea{
id:area
anchors.fill: parent
onClicked: parent.blurred = !parent.blurred
}
}
}
}
16、多媒体(Multimedia)
17、网络(NetWorking)
18、存储(Storage)
19、动态qml(Dynamic QML)
20、JavaScript
21、Qt and C++
22、C++扩展QML
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)