从 Qt 4.7 开始,Qt 引入了一种声明式脚本语言,称为 QML(Qt Meta Language 或者 Qt Modeling Language),作为 C++ 语言的一种替代。而 Qt Quick 就是使用 QML 构建的一套类库。 QML 是一种基于 JavaScript 的声明式语言。
每一个 QML 有且只有一个根元素,
一个 QML 文档分为 import 和 declaration 两部分。
qml的打印
使用:console.log(打印的字符串,打印的参数)
元素
根元素
每一个QML文件都需要一个根元素,并且只能有一个根元素。
window
Opacity---透明度
值在0~1之间
属性改变时会触发对于的属性改变槽函数
组件中的任何属性(包括自定义属性),都有改变时触发的槽函数
Item
属性和值
对于元素具有哪些属性可以直接查看QT帮助文档,让后进行设置就可以。
属性和属性可以设置的值都是已经定义好的,我们要做的就是知道属性和属性值的设置。
id
在其他元素中可以通过元素的id访问元素的属性
也可以自己使用自己的id访问自己的属性
x和y,z
相对于屏幕左上角
z为正数就靠平面前面
对于一个元素的x,y是在哪个位置
width和heigth
有这两个属性的组件,如果不设置这两属性,组件不显示。
focus
焦点
焦点所在对象就是要控制的对象;
如果对象没有获取焦点,是不能(键盘或者鼠标)被控制的。
锚点(anchor)
设置一个元素或者组件的位置可以设置x,y,z,也可以通过锚点设置。
位置指定
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
设置元素位置方式
1,x,y,z
2,anchors
rotation--旋转
顺时针旋转
scale---改变大小
width和heigth乘以指定的倍数
rectangle的gredient
设置颜色渐变
rectangle单边框设置
需要设置内外两个rectangle,通过设置margin(边缘)来设置两个rectangle的边缘宽度。
自定义组件:
import QtQuick 2.0
Rectangle{
id:root
width: 200
height: 100
color: "#ff3300"
//border.color: "#4c8dae"
property int m_topMargin: 0
property int m_bottomMargin: 0
property int m_leftMargin: 0
property int m_rightMargin: 0
Rectangle{
id: innerRect
anchors.fill: parent
color: "#ae7000"
anchors.topMargin: m_topMargin
anchors.bottomMargin: m_bottomMargin
anchors.leftMargin: m_leftMargin
anchors.rightMargin: m_rightMargin
}
}
main.qml调用
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
x:100
y:100
MyRectangle{
//id:myRect
x:200
y:200
// width: 200
// height: 100
m_topMargin: 10
m_bottomMargin: 10
}
}
state---states:[ ]
state
属性指定组件当前是使用哪个状态的属性。
states:[ ]
中指定这个组件的多种state(状态);
我们可以在states中设置组件的多种状态,在需要的不同时刻设置组件的state属性为states中的对应状态。
name是状态的名字;
PropertyChanges中可以设置这个状态的属性;
自定义文件中设置属性:
import QtQuick 2.0
Rectangle{
id:root
width: 200
height: 100
color: "#ff3300"
//border.color: "#4c8dae"
property int m_topMargin: 0
property int m_bottomMargin: 0
property int m_leftMargin: 0
property int m_rightMargin: 0
Rectangle{
id: innerRect
anchors.fill: parent
color: "#ae7000"
state: "normal"
anchors.topMargin: m_topMargin
anchors.bottomMargin: m_bottomMargin
anchors.leftMargin: m_leftMargin
anchors.rightMargin: m_rightMargin
states: [
State {
name: "normal"
PropertyChanges {target: innerRect; color:"#ae7000"}
},
State {
name: "red_color"
PropertyChanges { target: innerRect; color: "red" }
},
State {
name: "blue_color"
PropertyChanges { target: innerRect; color: "blue" }
}
]
MouseArea{
anchors.fill: parent
onPressed: {
innerRect.state="red_color"
}
onReleased: {
innerRect.state="blue_color"
}
}
}
}
动画效果属性
动画有8种类型
propertyAnimation
PropertyAnimation支持所有属性
sequentialAnimation
可持续多个动画效果
动画效果的两种实现方法
1,将动画效果设置为组件的属性
需要执行动画的时候,动画名.start()就开启属性。
Rectangle {
id: flashingblob
width: 75; height: 75
color: "blue"
opacity: 1.0
MouseArea {
anchors.fill: parent
onClicked: {
animateColor.start()
animateOpacity.start()
}
}
PropertyAnimation {id: animateColor; target: flashingblob; properties: "color"; to: "green"; duration: 100}
NumberAnimation {
id: animateOpacity
target: flashingblob
properties: "opacity"
from: 0.99
to: 1.0
loops: Animation.Infinite
easing {type: Easing.OutBack; overshoot: 500}
}
}
弊端:
即使是同类型的动画效果也要设置在各自的动画属性中:
2,on某个属性
在需要产生动画的位置直接开启动画
Rectangle {
id: rect
width: 100; height: 100
color: "red"
PropertyAnimation on x {
to: 200;
duration: 1500
}
PropertyAnimation on y {
to: 100
duration: 1500
}
NumberAnimation on width{
to:300
duration: 1500
}
}
transitions---states
transitions中指定states中状态变换,并且实现动画效果。
不需要开启transitions中的转变,只要指定的状态发送改变transitions就会自动执行。
Rectangle {
width: 75; height: 75
id: button
state: "RELEASED"
MouseArea {
anchors.fill: parent
onPressed: button.state = "PRESSED"
onReleased: button.state = "RELEASED"
}
states: [
State {
name: "PRESSED"
PropertyChanges { target: button; color: "#801dae"}
},
State {
name: "RELEASED"
PropertyChanges { target: button; color: "#dc3023"}
}
]
transitions: [
Transition {
from: "PRESSED"
to: "RELEASED"
ColorAnimation { target: button; duration: 1500}
},
Transition {
from: "RELEASED"
to: "PRESSED"
ColorAnimation { target: button; duration: 1500}
}
]
}
property
property可以用来声明所有类型的属性
可以声明基本数据类型,元素,和组件
声明是可以指定属性的值,也可以不用指定,使用到的时候再传参。
requerd property
要求属性必须要有赋值,无论是定义的时候,还是过程中。
property----var
使用var(variable--变量)来声明变量,Qt自动推导类型,不需要设计者关系设计的类型。
property----list<>
声明一个数组--property list<Rectangle>
property定义的属性加上权限
这个属性只能读取,不能改变。
property alias
别名
可以给组件,或者组件的属性取别名。
Rectangle背景设置为透明色,而不是白色
自定义属性
添加自己定义的属性需要使用property修饰符,然后跟上类型,名字和可选择的初始化值(property : )。如果没有初始值将会给定一个系统初始值作为初始值。注意如果属性名与已定义的默认属性名不重复,使用default关键字你可以将一个属性定义为默认属性。这在你添加子元素时用得着,如果他们是可视化的元素,子元素会自动的添加默认属性的子类型链表(children property list)。
组件---component
为什么需要组件
组件的常用槽函数
onCompleted()
窗口创建的时候触发
onDestruction()
窗口销毁时触发
component中创建组件是不会被自动创建的
需要Loader加载控件
通过source加载:source+元素路径
sourceComponent:+组件id
sourceComponent=null时loader加载的组件将被销毁
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")
x:100
y:100
Component{
id:m_comp
Rectangle{
id:comp_rect
width:100
height: 100
color: "#a98175"
Component.onCompleted: {
console.log("create");
}
Component.onDestruction: {
console.log("destructed");
}
}
}
Loader{
id:loader
//source: "/MyRectangle.qml"
sourceComponent: m_comp
onStatusChanged: {
console.log("loader status:",status);
}
}
Button{
id:button
x:300
y:300
width:100
height: 100
onClicked: {
loader.sourceComponent=null;
}
}
}
怎么获取component
loader的id加上item---loaderId.item返回组件根元素
Loader的异步--asynchronous
此属性保存组件是否将异步实例化。默认情况下,该属性为false。
当与源属性一起使用时,加载和编译也将在后台线程中执行。异步加载将创建组件跨多个框架声明的对象,并降低动画中的故障。当异步加载时,状态将更改为Loader.Load。一旦创建了整个组件,项目将可用,状态将更改为Loader.Ready。在进行异步加载时,将此属性的值更改为false将强制立即同步完成。如果必须在异步加载完成之前访问Loader内容,这允许开始异步加载,然后强制完成。
anchors怎么设置组件中根元素的位置
Text
Text组件中设置文字相关信息
Image元素
Image元素属性
source加载图片
AnimatedImage加载动态图
image只能加载静态图片
属性
暂停,是否播放等
MouseArea
鼠标区域元素
这个元素需要配合rectangle元素一起使用,需要使用rectangle包含或者填充。
因为MouseArea没有自己的边界控制范围,需要矩形框控制。
设置鼠标可控范围:
anchors.fill
mouseArea的属性
clicked=pressed+released
mouseArea的acceptedButton默认是左键,怎么设置右键
pressButtons属性记录鼠标键值
怎么获取鼠标的左右中键值
多条件联合判断
组件检测鼠标悬浮
containsPress属性记录鼠标是否按下
containsMouse记录鼠标是否存在MouseArea区域内
containsMouse和hoverEnble有关
按下可检测
MouseArea{
width: 200
height: 200
acceptedButtons: Qt.AllButtons
Rectangle{
id:mouse_rect
anchors.fill: parent
color: "#a4e2c6"
}
onContainsMouseChanged: {
console.log("Mouse cursor status:",containsMouse);
}
onContainsPressChanged: {
console.log("Press status:",containsPress);
}
}
悬浮可检测
MouseArea{
width: 200
height: 200
acceptedButtons: Qt.AllButtons
hoverEnabled: true //设置悬浮使能
Rectangle{
id:mouse_rect
anchors.fill: parent
color: "#a4e2c6"
}
onContainsMouseChanged: {
console.log("Mouse cursor status:",containsMouse);
}
onContainsPressChanged: {
console.log("Press status:",containsPress);
}
}
drag---拖动属性
要设置可拖动,至少要设置:可拖动目标
如果axis(轴)没有设置,默认可随意拖动。
minimum和maximum如果没有设置,默认可随意拖动。
Rectangle {
id: container
width: 600; height: 200
Rectangle {
id: rect
width: 50; height: 50
color: "red"
opacity: (600.0 - rect.x) / 600
MouseArea {
anchors.fill: parent
drag.target: rect //1---拖动的对象
drag.axis: Drag.XAxis //2---拖动的方向
drag.minimumX: 0 //3---往左托的最远距离
drag.maximumX: container.width - rect.width //4---往右托的最远距离
}
}
}
drag.filterChildren
MouseArea的drag.filterChildren如果是false则表示让这个mouseArea中的子元素mouseArea不具有(不继承)这个MouseArea的设置的属性。
注意:是mouseArea和内部mouseArea的关系,不是mouseArea和其他元素的关系。
Rectangle {
width: 480
height: 320
Rectangle {
x: 30; y: 30
width: 300; height: 240
color: "lightsteelblue"
MouseArea {
anchors.fill: parent
drag.target: parent;
drag.axis: "XAxis"
drag.minimumX: 30
drag.maximumX: 150
drag.filterChildren: false
Rectangle {
color: "yellow"
x: 50; y : 50
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: console.log("Clicked")
}
}
}
}
}
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick 2.7
Window {
id:m_window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
x:100
y:100
Rectangle{
id:root
width:300
height: 100
color: "#00bc12"
MouseArea{
id:root_mouse
anchors.fill: parent
drag.target: root
//drag.axis: Drag.XAndYAxis
drag.minimumX: 0
drag.maximumX: m_window.width-root.width
drag.minimumY: 0
drag.maximumY: m_window.height-root.height
drag.filterChildren: false
Rectangle{
id:mouse_rect
width: 100
height: 100
color: "#ffb61e"
MouseArea{
anchors.fill: parent
}
}
}
}
}
enable
控制MouseArea是否可用(是否使能)
mouseX,mouseY
记录鼠标的坐标
hoverEnable为false时,鼠标点击,这两个属性才有用。
Rectangle{
id:mouse_rect
width: 100
height: 100
color: "#ffb61e"
MouseArea{
anchors.fill: parent
hoverEnabled: false
onMouseXChanged: {
console.log("Mouse x is:",mouseX);
}
onMouseYChanged: {
console.log("Mouse y is:",mouseY);
}
}
}
onPressAndHold槽函数----pressAndHoldInterval
长安才会触发这个函数
长安多少时间才会触发和pressAndHoldInterval 属性有关
propagateComposedEvent---传播合成事件属性
mouse.accepted
默认情况下,各自mouseArea的事件只会是benmouseArea可以捕获;
如果需要子类的mouseArea也可以被父类捕获可以设置子类propagateComposedEvent属性和mouse.accepted属性
propagateComposedEvent属性的值为true,mouse.accepted为false表示可以向父级mouseArea传播本mouseArea的事件;
Rectangle {
color: "yellow"
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: console.log("clicked yellow")
}
Rectangle {
color: "blue"
width: 50; height: 50
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: {
console.log("clicked blue")
mouse.accepted = false
}
Rectangle{
id:three_rect
width: 20
height: 20
color: "#00e500"
MouseArea{
anchors.fill: parent
onClicked: {
console.log("clicked green");
}
}
}
}
}
}
如何向子类传播父类的事件
onDoubleClicked()
双击触发
Rectangle{
id:three_rect
width: 20
height: 20
color: "#00e500"
MouseArea{
anchors.fill: parent
onClicked: {
console.log("clicked green");
}
onDoubleClicked: {
console.log("Green was double clicked");
}
}
}
BUTTON
button默认是有背景色的;
属性
flat
flat为truebutton没有操作时没有默认背景色
checkable
需求:标志鼠标是否可以被选中
默认情况下button是不能被选中的,checkable为false,平淡色,如果checkable变为true,表示button可以被选中,色调加深。
注意:checkable属性并不是可选中和不可选中中的一个,而是表示button是否可以被选中。
Button{
id:root_button
width: 50
height: 50
checkable: true
}
atuoExclusive----自动独占属性
需求:让位于同一个元素中的所有button,任意时刻都只有一个可以被checked(选中),选中一个,其他的就自动变为未选中状态。
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick 2.7
import QtQuick.Controls 2.15
Window {
id:m_window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
x:100
y:100
Button{
id:root_button1
width: 50
height: 50
checkable: true
autoExclusive: true
}
Button{
id:root_button2
width: 50
height: 50
x:60
checkable: true
autoExclusive: true
}
Button{
id:root_button3
width: 50
height: 50
x:120
checkable: true
autoExclusive: true
}
}
autoRepeat
autoRepeat默认未false,如果为true,则表示如果一直按住button,就会一直触发pressed,realesed和clickedi信号。
autoRepeatDelay------按下Button之后多久触发p,r,c信号。
autoRepeatInterval---多久触发一次p,r,c信号。
text
给,button加上文字说明。
background
因为Button不是继承item,所以没有item的基础属性,比如颜色,透明度等;而如果需要设置itemd的属性,就需要background属性,background属性的值为item,可以在background的item中设置button的其他属性。
Button {
id: control
text: qsTr("Button")
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
color: control.down ? "#d0d0d0" : "#e0e0e0"
}
}
down
Button是否被按下
CheckBox
可选框
ChekcBox的属性
text
设置可选框的修饰文字
tristate
控制checkbox是否具有checkstate的三种状态:
checkstate
可选框的三种状态
checkBox独占可选属性
checkBox本身并不具备像button那样的autoExclusive独占属性。
怎么办:
两种方法:
1,把checkBox组件放入buttonGroup容器种,结组button属性事项独占。
Column{
id:col
CheckBox {
checked: true
text: qsTr("First")
}
CheckBox {
text: qsTr("Second")
}
CheckBox {
checked: true
text: qsTr("Third")
}
}
ButtonGroup{
id: btng
buttons: col.children
}
2,在CheckBox中设置ButtonGroup.group属性的值为一个ButtonGroup组件。
Column{
id:col
CheckBox {
checked: true
text: qsTr("First")
ButtonGroup.group: btng
}
CheckBox {
checked: true
text: qsTr("Second")
ButtonGroup.group: btng
}
CheckBox {
checked: true
text: qsTr("Third")
ButtonGroup.group: btng
}
}
ButtonGroup{
id: btng
buttons: col.children
}
怎么设置自己想要的checkstate的三种状态的切换关系
nextCheckState
注意:这个属性后面的值是一个(回调)函数,以函数返回值作为属性的值。
CheckBox {
id:root_checkBox
text:"here"
tristate: true
checkState: "Unchecked"
nextCheckState: function(){
if (checkState === Qt.Checked){
return Qt.Unchecked;
}
else if (checkState === Qt.Unchecked){
return Qt.PartiallyChecked;
}
else{
return Qt.Checked;
}
}
}
ButtonGroup
buttons
存放ButtonGroup需要记录的所有组件
exclusive
获取组件种的所有组件
组件.children
Column{
id:col
CheckBox {
checked: true
text: qsTr("First")
}
CheckBox {
text: qsTr("Second")
}
CheckBox {
checked: true
text: qsTr("Third")
}
}
ButtonGroup{
id: btng
buttons: col.children
}
RadioButton
属性
独占性
RadioButton会自动实现独占性
DelayButton
属性
Switch
条形按钮
属性
独占性
不会自动独占
需要借助ButtonGroup,像CheckBox一样使用。
TabButton
属性
独占性
自动独占
信号和槽函数
信号的定义:
signal 信号函数名()
信号触发(槽函数):
on+信号函数名:{}
信号函数名首字母大写
键盘触发的槽函数
Keys.槽函数
函数
qstr()
qsTr()函数就是 QObject::tr()函数的 QML 版本,用于返回可翻译的字符串。
real
real在qml中代表小数
怎么添加qml文件
qml文件的调用原理
项目入口是main.qml文件,文件中使用window组件实现基础的窗口。
其他自定义的文件就相当于自己定义的一个组件,可以在自定义文件中设置这个自定义组件的属性,然后在main.qml文件中通过调用自定义文件名调用自定义组件,在调用中设置自定义文件中设置的属性。
main.qml中调用的自定义组件不要再加id属性,因为main中就是使用,而不是定义了。
main.qml调用其他文件元素和组件
qml项目运行的是main.qml文件,其他文件元素和组件要运行需要在main.qml中调用
在main.qml中直接调用其他qml文件的文件名,就会运行被调用文件中的设置。