一个QML文件定义了一个独立的、顶级的QML组件。
一个QML组件就是一个模板,被QML运行环境解释来创建一个带有一些预定义行为的对象。
一个独立的QML组件可以运行多次来禅城多个对象,每个对象都可以称为该组件的实例。
例子:
在项目中添加一个Mywidget.qml文件
添加以下代码:
import QtQuick 2.9
Rectangle{
width: 100
height:100
Text{
anchors.fill:parent
font.bold: true
font.pixelSize: 20
text: "矩形"
}
}
在main.qml中添加以下代码:
Column{
spacing: 20
//创建了3个Mywidget组件
Mywidget{
id:widget1
}
Mywidget{
id:widget2
}
Mywidget{
id:widget3
}
}
任意的QML代码片段都可以称为一个组件,只需要将它放入一个 Xxxx.qml文件中,但必须以大写字母开头。
内联组件:
内联组件使用Component元素声明,拥有常规顶级组件的所有特性。
内联组件并不会自动呈现和显示 :
Rectangle{
width: 300
height: 300
color: "lightblue"
Component{
id:component1
Rectangle{
width: 100
height: 100
color: "green"
}
}
}
使用加载器加载:
Rectangle{
width: 300
height: 300
color: "lightblue"
Component{
id:component1
Rectangle{
width: 100
height: 100
color: "green"
}
}
}
Loader{sourceComponent: component1}
也可以为视图提供图形组件:
例如:使用ListView 中的delegate 来获取Component
Rectangle{
width: 300
height: 300
color: "lightblue"
Component{
id:component1
Rectangle{
width: 100
height: 100
color: "green"
}
}
ListView{
anchors.fill:parent
model: contactModel//显示的模型
delegate:component1//代理
}
}
相当于:
Rectangle{
width: 300
height: 300
color: "lightblue"
ListView{
anchors.fill:parent
model: contactModel//显示的模型
delegate:Rectangle{
width: 100
height: 100
color: "green"
}
}
}
在组件中添加属性、函数和信号
添加属性:
属性:可以在外部进行访问来修改一个对象,如Rectangle的width属性
- 一个属性就是一个QML组件中的一个值,可以被其他对象读取和修改
- 属性可以用于属性绑定,可以和其他属性同步修改
定义一个新属性的语法:
[default] property<type><name>[:defaultValue]
Rectangle{
id:rect1
property string image1: "qrc:/pix/ggg.png" //创建一个新属性
width:200
height: 200
color: "lightBlue"
Image {
anchors.fill:parent
source: rect1.image1//使用新属性
}
}
QML常见的属性类型:
QML类型 | 默认值 | C++(Qt) |
int | 0 | int |
bool | false | bool |
double | 0.0 | double |
real | 0.0 | double |
string | "" | QString |
url | "" | QUrl |
color | #000000(黑色) | QColor |
date | 未定义 | QDateTime |
variant | 未定义 | QVariant |
默认属性:
- 可以在声明属性时选default,可以使该属性成为默认属性
- 允许其他对象来指定默认属性值来作为子元素
Item元素默认属性为children属性:
Item{
Rectangle{}
Rectangle{}
}
如果children属性不是Item的默认属性的话,需要使用children[ ]
Item{
children: [
Rectangle{},
Rectangle{}
]
}
属性的别名:
属性别名是更高级的属性声明形式,属性别名不需要分配新的存储空间,可以通过别名来对属性进行操作。
别名的格式:类型被省略,但一定要加上alias关键词。
[dafault] property alias <name> :<alias reference>
alias关键字允许我们转发一个属性或者转发一个属性对象自身到另一个作用域
使用的注意事项:
- 只有在指定它们的部件创建完时,别名才可用,在组件本身创建时不能直接使用别名属性
- 别名引用不能使用在同一个部件中声明的另一个别名属性
- 一个别名属性可以和现有的属性使用相同的名称
//只有在指定它们的部件创建完时,别名才可用,在组件本身创建时不能直接使用别名属性
property alias label:text1.text
alis:"GGGGG"//使用时text1.text还没定义
//别名引用不能使用在同一个部件中声明的另一个别名属性
id:root
property alias buttonText:textItem.text
property alias buttonText2:root.buttonText
//一个别名属性可以和现有的属性使用相同的名称
Rectangle{
property alias color:childRect.color
color:"red"
Rectangle{id:childRect}
}
在这里color操作的都是childRect的color
例子:(添加一个Mywidget.qml文件)
import QtQuick 2.9
Rectangle{
property alias label:text1 //起别名,使得另一个qml文件也可以访问
width: 100
height:100
Text{
id:text1
anchors.fill:parent
font.bold: true
font.pixelSize: 20
text: "矩形"
}
}
在main.qml中创建一个Mywidget对象:
Rectangle{
Mywidget{
id:mywidget1
label.text:"ppppppp"//通过别名访问Text中的内容
}
}
添加函数
QML中可以使用JavaScript代码的函数,这些函数可以在内部调用,也可以被其他对象调用。
函数格式:
function <name>([<parameter name][,...])
{<body>}
- 声明可以出现在任何地方,但一般出现在顶部,方便查看
- 函数的参数类型为variant,所以不需要函数参数类型
无参函数 :
function fun1(){
console.log("无参函数")
}
有参函数:
function fun1(s1,s2){
console.log("s1+s2为",s1+s2)
}
有返回值的函数:
function fun1(s1,s2){
return Math.max(s1,s2)//返回这两个的最大值
}
常用的数学函数:格式:Math.xxx
添加信号
当一个事件发生时可以发射信号。信号的声明可以放到任意位置,但一般放置在开头。
信号格式为:
signal <name>[([<type> <parameter name>[,...]])]
信号没有参数的话可以省略()
例子:
Item{
signal click
signal hovered()
signal performAction(string action,variant actionArgument)
}
连接的创建:on<SignalName>来命名,信号名的第一个字母要大写
//上面对应的槽函数
onClicked
onHovered
onPerformAction
触发信号:直接调用函数即可
例子:创建一个Mywidget.qml
import QtQuick 2.9
Rectangle{
id:rect1
signal buttonClicked(int X,int Y)
width: 100
height:100
MouseArea{
anchors.fill:parent
onClicked: {
rect1.buttonClicked(mouse.x,mouse.y)//鼠标点击后,触发信号
}
}
}
main.qml中添加
Mywidget{
width: 100
height: 100
//槽函数
onButtonClicked: {
console.log("鼠标位置为:"+X+","+Y);
}
}
将信号关联到其他函数和信号上
使用connect()函数,可以将一个信号关联到一个函数或者其他信号上
创建一个Mywidget.qml:
import QtQuick 2.9
Rectangle{
id:rect1
signal buttonClicked(int X,int Y)
width: 100
height:100
MouseArea{
anchors.fill:parent
onClicked: {
rect1.buttonClicked(mouse.x,mouse.y)//鼠标点击后,触发信号
}
}
}
main.qml中添加:
Item{
anchors.fill:parent
id:item1
function text1(){ //创建一个函数
console.log("新的函数运行")
}
Mywidget{
width: 100
height: 100
Component.onCompleted: buttonClicked.connect(item1.text1)//将信号关联到text1上
}
}
使用connections连接
on<SignalName>无法使用的情况:
- 需要对同一信号进行多次连接
- 在信号发送方范围之外创建连接
- 连接到QML未定义的目标
例子:Mywidget.qml
import QtQuick 2.9
Rectangle{
id:rect1
signal buttonClicked(int X,int Y)
width: 100
height:100
MouseArea{
anchors.fill:parent
onClicked: {
rect1.buttonClicked(mouse.x,mouse.y)//鼠标点击后,触发信号
}
}
}
main.qml
Item{
anchors.fill:parent
id:item1
function text1(){ //创建一个函数
console.log("新的函数运行")
}
Mywidget{
id:my1
width: 100
height: 100
}
Connections{
target: my1//关联到该控件
onButtonClicked:{
item1.text1()
}
}
}