QT开发(五十三)———QML基本元素
一、基本可视化项
可视元素具有几何坐标,会在屏幕上占据一块显示区域。
Item 基本的项元素,所有可视化项都继承Item
Rectangle 基本的可视化矩形元素
Gradient 定义一个两种颜色的渐变过程
GradientStop 定义个颜色,被Gradient使用
Image 在场景中使用位图
BorderImage (特殊的项) 定义一张图片并当做边界
AnimatedImage 为播放动画存储一系列的帧
Text 在场景中使用文本
TextInput 显示可编辑为文本
IntValidatorint 验证器
DoubleValidator double 验证器
RegExpValidator 验证字符串正则表达式
TextEdit 显示多行可编辑文本
1、Item
Item是所有可视元素中最基本的一个,是所有其它可视元素的父元素,所有其它可视元素都继承Item。Item本身没有任何绘制,作用是定义所有可视元素的通用属性。
分组 |
属性 |
几何 |
x和y用于定义元素左上角的坐标,width和height则定义了元素的范围。z定义了元素上下的层叠关系。 |
布局 |
anchors(具有 left、right、top、bottom、vertical 和 horizontal center 等属性)用于定位元素相对于其它元素的margins的位置。 |
键盘处理 |
Key和KeyNavigation属性用于控制键盘;focus属性则用于启用键盘处理,也就是获取焦点。 |
变形 |
提供scale和rotate变形以及更一般的针对 x、y、z 坐标值变换以及transformOrigin点的transform属性列表。 |
可视化 |
opacity属性用于控制透明度;visible属性用于控制显示/隐藏元素;clip属性用于剪切元素;smooth属性用于增强渲染质量。 |
状态定义 |
提供一个由状态组成的列表states和当前状态state属性;同时还有一个transitions列表,用于设置状态切换时的动画效果。 |
除了定义通用属性,Item另外一个重要作用是作为其它可视元素的容器。
2、Rectangle
Rectangle继承了Item,并在Item的基础之上增加了填充色属性、边框相关的属性。为了定义圆角矩形,Rectangle还有一个radius属性。下面的代码定义了一个宽150像素、高100像素,浅金属蓝填充,红色4像素的边框的矩形。
Rectangle { id: rect width: 150 height: 100 color: "lightsteelblue" border { color: "#FF0000" width: 4 } radius: 8 }
QML中的颜色值可以使用颜色名字,也可以使用#十六进制的形式。
Rectangle除了color属性外,还有一个gradient属性,用于定义使用渐变色填充。
Rectangle { width: 150 height: 100 gradient: Gradient { GradientStop { position: 0.0; color: "red" } GradientStop { position: 0.33; color: "yellow" } GradientStop { position: 1.0; color: "green" } } border.color: "slategray" }
gradient要求一个Gradient对象,Gradient对象需要一个GradientStop的列表。所谓渐变,就是指定在某个位置必须是某种颜色,中间的过渡色则由计算而得。 GradientStop对象就是用于指定某个位置的颜色,需要两个属性:position和color。前者是一个 0.0 到 1.0 的浮点数,说明y轴方向的位置,例如元素的最顶部是0.0,最底部是1.0,介于最顶和最底之间的位置可以用一个浮点数表示,也就是一个比例;后者是position位置的颜色值。GradientStop { position: 0.33; color: "yellow" }说明在从上往下三分之一处是黄色。
Rectangle必须同时指定(显式地或隐式地)宽和高,否则不能在屏幕上显示出来。
3、Text
Text元素最重要的属性当然就是text属性。这个属性类型是string。Text元素会根据文本和字体计算自己的初始宽度和高度。字体则可以通过字体属性组设置(例如font.family、font.pixelSize等)。如果要设置文本颜色,只需要设置color属性。
Text元素中的文本可以使用horizontalAlignment和verticalAlignment属性指定对齐方式。为了进一步增强文本渲染,可以使用style和styleColor两个属性。这两个属性允许我们指定文本的显示样式和样式的颜色。对于较长的文本,通常会选择在文本末尾使用 … ,elide属性允许指定 … 的显示位置。通过wrapMode属性可以指定换行模式。
Text { width: 160 height: 100 text: "A very very long text" elide: Text.ElideRight style: Text.Sunken styleColor: ‘#FF4444‘ verticalAlignment: Text.AlignTop font { pixelSize: 24 } }
Text元素的文本省略号位置在一行文本的右侧;具有一个#FF4444颜色的样式Sunken。Text元素的作用是显示文本,不会显示文本的任何背景。
4、Image
Image元素则用于显示图像。QML支持的图像格式有PNG、JPG、GIF 和 BMP 等。可以直接给source属性一个URL来自动从网络加载图片,可以通过fillMode属性设置改变大小的行为。
URL可以是本地路径,可以是网络路径。如果一个URL是网络的,QML 会自动从URL网络地址加载对应的资源。
Image { x: 0; y: 0 width: 97 height: 120 source: "http://ucenter.51cto.com/avatar.php?uid=9281927&size=middle" fillMode: Image.PreserveAspectCrop clip: true }
Image.PreserveAspectCrop是等比例切割,需要同时设置clip属性,避免所要渲染的对象超出元素范围。
5、TextInput
TextInput是单行的文本输入框,支持验证器、输入掩码和显示模式等
import QtQuick 2.0 Rectangle { width: 200 height: 80 color: "blue" TextInput { id: input1 x: 8; y: 8 width: 96; height: 20 focus: true text: "Text Input 1" KeyNavigation.tab: input2 } TextInput { id: input2 x: 8; y: 36 width: 96; height: 20 text: "Text Input 2" KeyNavigation.tab: input1 } }
有两个TextInput,用户可以通过点击输入框改变焦点。如果想支持键盘导航,可以添加KeyNavigation附加属性。KeyNavigation是一个附加属性。当用户点击了指定的按键时,属性指定的组件就会获得焦点。普通的属性隶属于类型;附加属性一般用于修饰或补充目标类型。KeyNavigation.tab并不是TextInput的普通属性,是用来说明TextInput的一种特征。附加属性的一般语法是类型.属性名,类型就是KeyNavigation,属性名就是tab。
6、TextEdit
TextEdit是多行的文本编辑组件
import QtQuick 2.0 Rectangle { width: 200 height: 80 color: "blue" TextEdit { id: edit1 x: 8; y: 8 width: 96; height: 20 focus: true text: "Text Edit 1" KeyNavigation.tab: edit2 } TextEdit { id: edit2 x: 8; y: 36 width: 96; height: 20 text: "Text Edit 2" KeyNavigation.tab: edit1 } }
7、IntValidator
int 型验证器,和输入框结合后就是只能输入整型数据。
import QtQuick 2.0 TextInput { IntValidator{id: intval; bottom: 10; top: 100;} width: 100; height: 20; text: ""; validator: intval; }
8、BorderImage
BorderImage将一张图片分为9部分,当图片进行缩放的时候
A.1 3 7 9位置的都不会进行缩放
B. 2 8将根据属性horzontalTileMode 进行缩放
C.4 6 将根据属性verticalTileMode 进行缩放
D.5 将根据属性horzontalTileMode 和 verticalTileMode 进行缩放
import QtQuick 2.0 BorderImage { width: 180; height: 180 border { left: 30; top: 30; right: 30; bottom: 30 } horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch source: "http://ucenter.51cto.com/avatar.php?uid=9281927&size=middle" }
9、DoubleValidator
DoubleValidator 只能输入浮点数
TextInput { DoubleValidator { id: intval decimals: 4 bottom: 10 top: 100 notation: DoubleValidator.StandardNotation } width: 100; height: 20; text: ""; validator: intval; }
10、RegExpValidator
RegExpValidator使用正则表达式
TextInput { // 使用一个正则表达式来控制输入的字符串 // /^[a-zA-Z]{1}[0-1]{0,2}[a-z]{1,3}$/ 表示 开始位置必须是一个大写或小写字母 // 接下来是0~2个的数字而且是0或1,在接下来是1~3个的小写字母 RegExpValidator{id: intval; regExp:/^[a-zA-Z]{1}[0-1]{0,2}[a-z]{1,3}$/;} width: 100; height: 20; text: ""; validator: intval; }
11、AnimatedImage
AnimatedImage 主要用于播放gif图片
import QtQuick 2.0 Rectangle { width: animation.width; height: animation.height + 8 AnimatedImage { id: animation source: "animation.gif" } Rectangle { property int frames: animation.frameCount width: 4; height: 8 x: (animation.width - width) * animation.currentFrame / frames y: animation.height color: "red" } }
二、基本的交互项
不可视元素(例如Timer)通常提供一种作用于可视元素的功能。
MouseArea 鼠标句柄交互
FocusScope 键盘焦点句柄
Flickable 提供一种浏览整张图片的一部分的效果
Flipable提供一个平面,可以进行翻转看前面或后面
1、MouseArea
MouseArea用于用户交互,是一个不可见的矩形区域,用于捕获鼠标事件。通常会将MouseArea元素与一个可视元素结合起来使用,以便可视元素能够与用户交互。
Rectangle { id: rect x: 0; y: 0 width: 150; height: 100 color: "red" MouseArea { anchors.fill:parent onClicked: { Qt.quit(); } } }
MouseArea将可视化展示与用户输入控制解耦,可以显示一个较小的元素,但有一个很大的可交互区域,以便在界面显示与用户交互之间找到一个平衡(如果在移动设备上,较小的区域非常不容易被用户成功点击。苹果公司要求界面的交互部分最少要有 40 像素以上,才能够很容易被手指点中)。
2、FocusScope
Widget.qml文件:
import QtQuick 2.0 FocusScope { id: scope property alias color: rectangle.color x: rectangle.x; y: rectangle.y width: rectangle.width; height: rectangle.height Rectangle { id: rectangle anchors.centerIn: parent color: "lightsteelblue" width: 175; height: 30 radius: 10; antialiasing: true Text { id: label; anchors.centerIn: parent } focus: true Keys.onPressed: { if (event.key == Qt.Key_A) label.text = ‘Key A was pressed‘ else if (event.key == Qt.Key_B) label.text = ‘Key B was pressed‘ else if (event.key == Qt.Key_C) label.text = ‘Key C was pressed‘ } } MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } } }
使用Widget组件:
import QtQuick 2.0 Rectangle { id: widget width: 240; height: 150 color:"white"; Column { anchors.centerIn: parent; spacing: 15 Widget { color: "lightblue" } Widget { focus:true color: "palegreen" } } }
3、Flickable
QML中提供了一个Flickable元素,可以将其子项目设置在一个可以拖曳和弹动的界面上,使得子项目的视图可以滚动。Flickable不会自动剪裁它的内容,如果不是将它用作全屏项目,可以将clip属性设置为true来隐藏超出区域的内容。
import QtQuick 2.0 Flickable { width: 200; height: 200 contentWidth: image.width contentHeight: image.height //interactive: false //禁止拖动弹动功能 Image { id: image source: "http://ucenter.51cto.com/avatar.php?uid=9281927&size=middle" } }
4、Flipable
Flipable是一个可以明显在其正面和反面之间进行翻转的项目,同时使用Rotation、State和Transition等元素来产生翻转效果。front和back分别用来保存要显示在Flipable项目的正面和反面的项目。Flipable有一个flipped布尔值属性,每当在Flipable中的MouseArea上单击鼠标时都会切换该属性的值。当flipped为true时,项目变为back状态,在这个状态,Rotation的angle属性改变为180°来产生一个翻转效果。当flipped为false时,项目恢复到默认状态,angle的值为 0。
import QtQuick 2.6 Flipable { id: flipable width: 240; height:240 property bool flipped: false //正面、反面图片资源 front: Image{source: "1.jpg"; anchors.centerIn: parent} back: Image{source: "2.jpg"; anchors.centerIn: parent} transform: Rotation { id: rotation origin.x: flipable.width / 2 origin.y: flipable.height / 2 axis.x: 0; axis.y: 1; axis.z: 0 angle: 0 } states: State { name: "back" PropertyChanges { target: rotation; angle: 180 } //翻转效果 when: flipable.flipped } transitions: Transition { NumberAnimation {target: rotation; property: "angle"; duration: 800} } MouseArea { anchors.fill: parent onClicked: flipable.flipped = !flipable.flipped } }
三、状态
State 定义一个配置对象和属性的集合
PropertyChanges 使用一个State描述属性的改变
StateGroup 包含一个状态集合和状态变换
ParentChange 重新定义父集,也就是换个父节点
AnchorChanges 在一个状态中改变anchors
1、State
import QtQuick 2.0 Rectangle { id: rect width: 100; height: 100 color: "black" MouseArea { id: mouseArea anchors.fill: parent onClicked: rect.state == ‘clicked‘ ? rect.state = "" : rect.state = ‘clicked‘; } // 设置状态 states: [ State { name: "clicked" PropertyChanges { target: rect; color: "red" } } ] }
2、PropertyChanges
import QtQuick 2.0 Text { id: myText width: 100; height: 100 text: "Hello" color: "blue" states: State { name: "myState" PropertyChanges { target: myText text: "Goodbye" color: "red" } } MouseArea { anchors.fill: parent; onClicked: myText.state = ‘myState‘ } }
3、ParentChange
把指定的item换一个item父节点
import QtQuick 2.0 Item { width: 200; height: 100 Rectangle { id: redRect width: 100; height: 100 color: "red" } Rectangle { id: blueRect x: redRect.width width: 50; height: 50 color: "blue" states: State { name: "reparented" // 改变父节点 ParentChange { target: blueRect; parent: redRect; x: 10; y: 10 } } MouseArea { anchors.fill: parent; onClicked: blueRect.state = "reparented" } } }
4、AnchorChanges
import QtQuick 2.0 Rectangle { id: window width: 120; height: 120 color: "black" Rectangle { id: myRect; width: 50; height: 50; color: "red" } states: State { name: "reanchored" AnchorChanges { target: myRect anchors.top: window.top anchors.bottom: window.bottom } PropertyChanges { target: myRect anchors.topMargin: 10 anchors.bottomMargin: 10 } } // 鼠标事件 MouseArea { anchors.fill: parent; onClicked: window.state = "reanchored" } }
四、动画和变换
Behavior 默认的属性变换动画
SequentialAnimation 对定义的动画串行播放
ParallelAnimation 对定义的动画并行播放
PropertyAnimation 属性变换动画
NumberAnimation 对实数类型属性进行的动画
Vector3dAnimation 对QVector3d进行的属性
ColorAnimation 颜色进行的变换动画
RotationAnimation 对旋转进行的变换动画
ParentAnimation 对父节点进行变换的动画,改变绑定的父节点
AnchorAnimation 对anchor 进行改变的动画
PauseAnimation 延迟处理
SmoothedAnimation 允许属性平滑的过度
SpringAnimation 一种加速的效果
PropertyAction 允许在动画过程中对属性的直接改变
ScriptAction 允许动画过程中调用脚本
Transition 在状态变换中加入动作变化
1、Behavior
一个特定的属性值改变时要应用一个动画,可以使用一个Behavior为一个属性改变指定一个默认的动画。
import QtQuick 2.0 Rectangle { id: rect width: 100; height: 100 color: "red" // 针对宽度的动画 Behavior on width { NumberAnimation { duration: 1000 } } MouseArea { anchors.fill: parent onClicked: rect.width = 50 } }
2、SequentialAnimation
串行播放多个动画
Rectangle { id: rect1 width: 500; height: 500 Rectangle { id: rect; color: "red" width: 100; height: 100 // 串行播放多个动画,先横向移动,在纵向移动 SequentialAnimation { running: true; NumberAnimation {target:rect; properties:"x"; to: 50; duration: 1000 } NumberAnimation {target:rect; properties:"y"; to: 50; duration: 1000 } } } }
3、ParallelAnimation
import QtQuick 2.0 Rectangle { id: rect1 width: 500; height: 500 Rectangle { id: rect; color: "red" width: 100; height: 100 // 并行播放动画,同时横向和纵向移动 ParallelAnimation { running: true; NumberAnimation {target:rect; properties:"x"; to: 50; duration: 1000 } NumberAnimation {target:rect; properties:"y"; to: 50; duration: 1000 } } } }
4、PropertyAnimation
一个动画被应用为属性值源(property value source)。
import QtQuick 2.0 Rectangle { id: rect width: 100; height: 100 color: "red" states: State { name: "moved" PropertyChanges { target: rect; x: 50 } } transitions: Transition { // 属性动画 当属性 x或y发生变化的时候,就播放这样一个动画 PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad } } MouseArea { anchors.fill: parent; onClicked: rect.state = "moved"; } }
5、NumberAnimation
import QtQuick 2.0 Rectangle { width: 100; height: 100 color: "red" // 对当前item的x进行移动,目标移动到x = 50 NumberAnimation on x { to: 50; duration: 1000 } }
6、ColorAnimation
颜色过度
import QtQuick 2.0 Rectangle { width: 100; height: 100 color: "red" ColorAnimation on color { to: "yellow"; duration: 1000 } }
7、RotationAnimation
import QtQuick 2.0 Item { width: 300; height: 300 Rectangle { id: rect width: 150; height: 100; anchors.centerIn: parent color: "red" smooth: true states: State { name: "rotated"; PropertyChanges { target: rect; rotation: 180} } transitions: Transition { RotationAnimation { duration: 1000 direction: RotationAnimation.Counterclockwise } } } MouseArea { anchors.fill: parent; onClicked: rect.state = "rotated" } }
8、ParentAnimation
一个切换父节点的动画,平滑的过度
import QtQuick 2.0 Item { width: 200; height: 100 Rectangle { id: redRect width: 100; height: 100 color: "red" } Rectangle { id: blueRect x: redRect.width width: 50; height: 50 color: "blue" states: State { name: "reparented" ParentChange { target: blueRect parent: redRect x: 10; y: 10 } } transitions: Transition { ParentAnimation { NumberAnimation { properties: "x,y"; duration: 1000 } } } MouseArea { anchors.fill: parent onClicked: blueRect.state = "reparented" } } }
9、AnchorAnimation
import QtQuick 2.0 Item { id: container width: 200; height: 200 Rectangle { id: myRect width: 100; height: 100 color: "red" } states: State { name: "reanchored" AnchorChanges { target: myRect; anchors.right: container.right } } transitions: Transition { AnchorAnimation { duration: 1000 } } // 当控件加载完成后 Component.onCompleted: container.state = "reanchored" }
10、PauseAnimation
延迟效果
import QtQuick 2.0 Item { id: container width: 200; height: 200 Rectangle { id: myRect width: 100; height: 100 color: "red" SequentialAnimation { running: true; NumberAnimation {target: myRect;to: 50; duration: 1000; properties: "x"; } PauseAnimation { duration: 5000 } // 延迟100毫秒 NumberAnimation {target: myRect; to: 50; duration: 1000; properties: "y"; } } } }
11、SmoothedAnimation
平滑过度
import QtQuick 2.0 Rectangle { width: 800; height: 600 color: "blue" Rectangle { width: 60; height: 60 x: rect1.x - 5; y: rect1.y - 5 color: "green" Behavior on x { SmoothedAnimation { velocity: 200 } } Behavior on y { SmoothedAnimation { velocity: 200 } } } Rectangle { id: rect1 width: 50; height: 50 color: "red" } focus: true Keys.onRightPressed: rect1.x = rect1.x + 100 Keys.onLeftPressed: rect1.x = rect1.x - 100 Keys.onUpPressed: rect1.y = rect1.y - 100 Keys.onDownPressed: rect1.y = rect1.y + 100 }
12、SpringAnimation
平滑的过度过程,在动画结束的时候有种弹性的效果
import QtQuick 2.0 Item { width: 300; height: 300 Rectangle { id: rect width: 50; height: 50 color: "red" Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } } Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } } MouseArea { anchors.fill: parent onClicked: { rect.x = mouse.x - rect.width/2 rect.y = mouse.y - rect.height/2 } } }
13、PropertyAction
主要是在动画过程中直接的改变一个属性
import QtQuick 2.0 transitions:Transition { ... PropertyAction { target: theImage; property: "smooth"; value: true } ... }
14、ScriptAction
import QtQuick 2.0 SequentialAnimation { NumberAnimation { ... } ScriptAction { script: doSomething(); } NumberAnimation { ... } }
15、Transition
import QtQuick 2.0 Rectangle { id: rect width: 100; height: 100 color: "red" MouseArea { id: mouseArea anchors.fill: parent } states: State { name: "moved"; when: mouseArea.pressed PropertyChanges { target: rect; x: 50; y: 50 } } transitions: Transition { NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad } } }
五、数据项
Binding 在创建的时候绑定一些数据到一些属性
ListModel 定义链表数据
ListElement 定义ListModel的一个数据项
VisualItemModel 包含可视化项(visual items)到一个view中,相当是一个容器
VisualDataModel 包含一个model和一个delegate,model包含需要的数据,delegate设计显示的项的信息
Package 把VisualDataModel共享给多个view
XmlListModel 特殊的一个模式使用XPath表达式,使用xml来设置元素
XmlRole XmlListModel的一个特殊的角色
1、Binding
import QtQuick 2.0 Item { width: 300; height: 300 Text {id: app; text: "xxxfa"} TextEdit { id: myTextField; text: "Please type here..." } // 把myTextField和app的enteredText属性进行绑定 Binding { target: app; property: "enteredText"; value: myTextField.text } }
2、ListModel
import QtQuick 2.0 Rectangle { width: 200; height: 200 ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } } Component { id: fruitDelegate Row { spacing: 10 Text { text: name } Text { text: ‘$‘ + cost } } } ListView { anchors.fill: parent model: fruitModel delegate: fruitDelegate } }
3、VisualItemModel
import QtQuick 2.0 Rectangle { width: 100; height: 100; VisualItemModel { id: itemModel Rectangle { height: 30; width: 80; color: "red" } Rectangle { height: 30; width: 80; color: "green" } Rectangle { height: 30; width: 80; color: "blue" } } ListView { anchors.fill: parent model: itemModel } }
4、VisualDataModel
import QtQuick 2.0 Rectangle { width: 200; height: 100 VisualDataModel { id: visualModel model: ListModel { ListElement { name: "Apple" } ListElement { name: "Orange" } } delegate: Rectangle { height: 25 width: 100 Text { text: "Name: " + name} } } ListView { anchors.fill: parent model: visualModel } }
六、视图
ListView 提供一个链表显示模型试图
GridView 提供一个网格显示模型试图
PathView 提供一个内容沿着路径来显示的模型
Path 定义一个PathView使用的轨迹
PathLine 定义一个线性的轨迹
PathQuad 定义一个二次贝塞尔曲线的轨迹
PathCubic 定义一个三次贝塞尔曲线的轨迹
PathAttribute 允许绑定一个属性上,具体看例子
PathPercent 修改item分配的轨迹 不是很明了其中的意思
WebView 允许添加网页内容到一个canvas上
1、GridView
import QtQuick 2.0 Rectangle { width: 200; height: 400; ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } } GridView { anchors.fill: parent model: fruitModel delegate: Column { Text {text:"name" + name} Text {text:"cost"+ cost} } } }
2、PathView
import QtQuick 2.0 Rectangle { width: 200; height: 400; ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } } PathView { anchors.fill: parent model: fruitModel delegate: Column { Text {text:"name" + name} Text {text:"cost"+ cost} } path:Path { startX: 120; startY: 100 PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } } } }
3、PathLine
import QtQuick 2.0 Rectangle { width: 200; height: 400; ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } } PathView { anchors.fill: parent model: fruitModel delegate: Column { Text {text:"name" + name} Text {text:"cost"+ cost} } path:Path { startX: 150; startY: 120 PathLine { x: 200; y: 80; } PathLine { x: 100; y: 80; } PathLine { x: 150; y: 120; } } } }
4、PathAttribute
import QtQuick 2.0 Rectangle { width: 200; height: 400; ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } } PathView { anchors.fill: parent model: fruitModel delegate: Item { id: delitem; width: 80; height: 80; Column { Rectangle { width: 40; height: 40; scale: delitem.scale; color: "red" } Text {text:"name" + name} Text {text:"cost"+ cost} } } path: Path { startX: 120; startY: 100 PathAttribute { name: "Scale"; value: 1.0 } PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } PathAttribute { name: "Scale"; value: 0.3 } PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } } } }
5、WebView
import QtQuick 2.0 import QtWebKit 1.0 WebView { url: "http://www.nokia.com" preferredWidth: 490 preferredHeight: 400 scale: 0.5 smooth: false }
七、定位器
Column 整理它的子列(纵)
Row 整理它的子行(横)
Grid 设置它的子到一个网格上
Flow 目的是不让他的子项重叠在一起
QML提供的多种用于定位的元素叫做定位器,包含在 QtQuick模块。QML定位器主要有Row、Column、Grid和Flow等。
1、Column
Column将子元素按照加入的顺序从上到下,在同一列排列出来。spacing属性用于定义子元素之间的间隔。
Main.qml文件:
import QtQuick 2.0 Rectangle { id: root width: 120 height: 120 color: "blue" Column { id: row anchors.centerIn: parent spacing: 8 Button { color:"red" width:60 text:"hello" } Button { color:"green" width: 96 text:"close" } Button { color:"gray" width:60 } } }
2、Row
Row将其子组件放置在一行的位置,既可以设置从左向右,也可以设置从右向左,取决于layoutDirection属性。spacing属性用于指定子组件之间的间隔。
Main.qml文件:
import QtQuick 2.0 Rectangle { id: root width: 240 height: 80 color: "blue" Row { id: row anchors.centerIn: parent spacing: 8 Button { color:"red" width:60 text:"hello" } Button { color:"green" width: 96 text:"close" } Button { color:"gray" width:60 } } }
3、Grid
Grid元素将其子元素排列为一个网格,需要制定rows和columns属性,也就是行和列的数值。如果二者有一个不显式设置,则另外一个会根据子元素的数目计算出来。如果设置为3行,一共放入6个元素,列数会自动计算为2。flow和layoutDirection属性则用来控制添加到网格的元素的顺序。Grid元素也有spacing属性。
Main.qml文件:
import QtQuick 2.0 Rectangle { id: root width: 200 height: 200 color: "black" Grid { id: grid rows:2 anchors.centerIn: parent spacing: 8 Button { color:"red" width:60 text:"hello" } Button { color:"green" width: 96 text:"close" } Button { color:"gray" width:60 } } }
设定Grid的rows属性为2,添加3个子元素,columns属性会自动计算为2。
4、Flow
Flow定位器会将其子元素以流的形式显示出来。使用flow和layoutDirection两个属性来控制显示方式,可以从左向右横向布局,也可以从上向下纵向布局。添加到Flow里面的元素,当Flow的宽度或高度不足时,元素会自动换行。为了令Flow正确工作,需要指定其宽度或者高度。
Main.qml文件:
import QtQuick 2.0 Rectangle { id: root width: 200 height: 200 color: "black" Flow { anchors.fill: parent anchors.margins: 20 spacing: 8 Button { color:"red" width:60 text:"hello" } Button { color:"green" width: 80 text:"close" } Button { color:"gray" width:60 } } }
三个按钮组件边长分别是60,80,60px,整个主窗口的宽是200px,Flow元素外边距 20px,因此Flow的宽度其实是 200px – 20px – 20px = 160px。Flow子元素间距为20px,两个按钮组件所占据的宽度就已经60px + 20px + 80px = 160px,3个则是160px + 20px + 60px = 240px > 200px,默认窗口大小一行只能显示两个按钮组件,第三个按钮组件自动换行。当拖动改变窗口大小时,可以观察Flow元素是如何工作的。如果拖动窗口宽度变长时,第三个按钮组件将会显示在第一行,如果拖动拖动窗口宽度变窄时,第二、三个按钮组件会换行到第二行、第三行。
5、Repeater
Repeater是一个结合定位器一起使用的元素。Repeater像一个for循环,能够遍历数据模型中的元素。
import QtQuick 2.0 Rectangle { id: root width: 268 height: 268 color: "black" property variant colorArray: ["#00bde3", "#67c111", "#ea7025", "#ff0000"] Grid { anchors.fill: parent anchors.margins: 8 spacing: 4 Repeater { model: 16 Rectangle { width: 60; height: 60 property int colorIndex: Math.floor(Math.random()*4) color: root.colorArray[colorIndex] border.color: Qt.lighter(color) Text { anchors.centerIn: parent color: "black" text: "Cell " + index } } } } }
将Repeater同Grid一起使用,Repeater作为Grid的数据提供者。Repeater的model可以是任何能够接受的数据模型,并且只能重复基于Item的组件。重复生成16个定义的Rectangle元素。
Repeater会按照model属性定义的个数循环生成其子元素。每一次循环,Repeater都会创建一个矩形作为自己的子元素。新生成的矩形的颜色按照Math.floor(Math.random()*3)的算法计算而得。颜色选择算法会得到 0,1,2,4四者之一,用于选择数组colorArray中预定义的颜色。JavaScript是QtQuick 的核心部分,JavaScript标准函数都是可用的。
Repeater会为每一个子元素注入一个index属性,就是当前的循环索引,可以在子元素定义中直接使用index属性。
使用Repeater时,需要注意性能问题。处理很大的数据模型,或者需要动态获取数据时,Repeater代码会非常吃力,需要另外的实现。Repeater不适用于处理大量数据或者动态数据,仅适用于少量的静态数据的呈现。
八、实用项
Connections 明确连接信号和信号句柄
Component 封装QML items 想一个组件一样
Timer 提供时间触发器
QtObject 基本的元素只包含objectName属性
Qt qml全局Qt object提供使用的枚举和函数
WorkerScript 允许在QML使用线程
Loader 控制载入item或组件
Repeater 使用一个模型创建多个组件
SystemPalette 为Qt palettes提供一个通道
FontLoader 载入字体根据名字或URL
LayoutItem 允许声明UI元素插入到qtGraphicsView 布局中
1、Connections
import QtQuick 2.0 Rectangle { width: 100; height: 100; MouseArea { id: area anchors.fill: parent; } Connections { target: area onClicked: { console.log(" ok");} } }
2、Component
import QtQuick 2.0 Item { width: 100; height: 100 Component { id: redSquare Rectangle { color: "red" width: 10 height: 10 } } // 动态的载入一个组件 Loader { sourceComponent: redSquare } Loader { sourceComponent: redSquare; x: 20 } }
3、Timer
import QtQuick 2.0 Item { width: 200; height: 40; Timer { interval: 500; running: true; repeat: true onTriggered: time.text = Date().toString() // 使用javascript获取系统时间 } Text { id: time } }
4、Repeater
import QtQuick 2.0 Row { Repeater { model: 3 Rectangle { width: 100; height: 40 border.width: 1 color: "yellow" } } }
5、SystemPalette
Rectangle { SystemPalette { id: myPalette; colorGroup: SystemPalette.Active } width: 640; height: 480 color: myPalette.window Text { anchors.fill: parent text: "Hello!"; color: myPalette.windowText } }
6、FontLoader
Column { FontLoader { id: fixedFont; name: "Courier" } FontLoader { id: webFont; source: "http://www.mysite.com/myfont.ttf" } Text { text: "Fixed-size font"; font.family: fixedFont.name } Text { text: "Fancy font"; font.family: webFont.name } }
九、变换
Scale 分派item 缩放行为
Rotation 分派item 旋转行为
Translate 分派item 移动行为
1、Scale
import QtQuick 2.0 Rectangle { width: 100; height: 100 color: "blue" Rectangle { x: 50; y: 50; width: 20; height: 20; color: "red" transform: Scale { origin.x: 10; origin.y: 10; xScale: 3} } }
2、Rotation
import QtQuick 2.0 Rectangle { width: 100; height: 100 color: "blue" // 绕位置25,25 旋转45度 transform: Rotation { origin.x: 25; origin.y: 25; angle: 45} }
3、Translate
import QtQuick 2.0 Row { Rectangle { width: 100; height: 100 color: "blue" // 沿y轴正方向移动20个像素 transform: Translate { y: 20 } } Rectangle { width: 100; height: 100 color: "red" // 沿y轴负方向移动20个像素 transform: Translate { y: -20 } } }
十、元素布局
除了定位器,QML 还提供了另外一种用于布局的机制:锚点(anchor)。锚点允许我们灵活地设置两个元素的相对位置,使两个元素之间形成一种类似于锚的关系,也就是两个元素之间形成一个固定点。锚点的行为类似于一种链接,它要比单纯地计算坐标改变更强。锚点描述的是相对位置,在使用锚点时,必须指定两个元素,声明其中一个元素相对于另外一个元素。锚点是Item元素的基本属性之一,因而适用于所有QML可视元素。
一个元素有6个主要的锚点的定位线:top、bottom、left、right、horizontalCenter和verticalCenter。对于Text元素,还有一个baseline锚点。每一个锚点定位线都可以结合一个偏移的数值。top、bottom、left和right称为外边框;horizontalCenter、verticalCenter和baseline称为偏移量。
import QtQuick 2.0 Rectangle { width: 200 height: 200 color: "blue" border.color: Qt.lighter(color) MouseArea { anchors.fill: parent drag.target: parent } }
MouseArea组件是一个用于处理鼠标事件的组件。drag.target: parent说明拖动目标是parent,拖动对象是MouseArea的父组件,即Rectangle组件。anchors.fill设置内部蓝色矩形的锚点为填充(fill),填充的目的对象是parent;anchors.margins: 10表示填充边距是10px。虽然设置了矩形宽度为12px,但锚点的优先级要高于宽度属性设置,所以蓝色矩形的实际宽度是100px – 10px – 10px = 80px。
import QtQuick 2.0 Rectangle { id: root width: 220 height: 220 color: "black" Rectangle { x: 10 y: 10 width: 100 height: 100 color:"blue" Rectangle { x:8 y: 8 width:60 height:60 color:"green" anchors.left: parent.left anchors.leftMargin: 8 MouseArea { anchors.fill: parent drag.target: parent } } } }
anchors.left设置内部绿色矩形的锚点为父组件的左边线(parent.left);左边距是8px。可以试着拖动绿色矩形,拖动绿色矩形时,绿色矩形只能沿着距离父组件蓝色矩形左边8px的位置上下移动。
anchors.left: parent.right设置锚点的左侧为父组件的右侧
anchors.top: parent.bottom设置锚点的上侧为父组件的底侧
anchors.topMargin: 4设置锚点的上侧边距为4
anchors.horizontalCenter: parent.horizontalCenter设置锚点的水平中心为父组件的水平中心