import QtQuick
QML类型系统
对象特性
1.id特性:每个qml对象都有一个唯一id
2.属性特性:属性是对象的一个值,可以是动态的,也可以是静态的
2.1声明:
C++中通过Q_PROPERTY宏:
QML中通过 property propertyType propertyName—>例子:property color nextColor
声明了一个color类型的nextColor属性,隐式为该属性创建了一个<信号处理器>onNextColorChanged,
如果nextColor值改变就会触发,即称之为<值改变信号>
例如
Rectangle
{
property color nextColor
onNextColorChanged:
doSomething()
nextColor:red
}
2.2对象类型也可以作为属性类型:property Rectangle someRectangle
2.3属性初始化:
property var someNumber:1.5
property var someString:“abc”
property var someBool:true
property var someList:[1,21,“three”,“four”]
property var someObj:Rectangle{width:100;height:100,color:“red”}
2.4属性赋值: id.propertyName = value
3.对象列表属性:可以将一个qml对象类型赋值给列表类型的属性
对象列表属性:可以将一个qml对象类型赋值给列表类型的属性
声明一个列表属性:property list propertyName
Rectangle
{
property list subRec //声明不初始化
//声明且初始化
property list subRec1:[Rectangle{width:100;height:100,color:“red”},Rectangle{width:100;height:100,color:“red”}]
//subRec1.length 是长度 访问通过subRec1[index]
}
4.属性组
属性可以包含子属性,子属性可以通过点标记或组标记赋值 Text {
font.pixelSize:12;font.bold:true //点标记
text:“123” } Text {
font{pixelSize:12;bold:true} //组标记
text:“123” }
5.属性别名
5.1别名类似于引用, property alias propertyName : reference ------>property alias buttonText:textItem.text
可以直接使用,上述buttonText就是属性别名,对其的修改都是作用的textItem.text
Rectangle
{
property alias buttonText:textItem.text
width:100;height:100
Text{id:textItem}
}
Button{buttonText:"click me"}
5.2别名可以和现有属性同名但是会覆盖现有属性尽量避免.超过两层引用将失效
6.默认属性
默认属性至多只有一个 default property var name
当声明对象时,若其子对象没有明确指定要分配到的属性名,那么子对象就被赋值给默认属性 例子:
在一个Label.qml文件中
Text{
default property var someText
text:“Hello”+someText.text
}
在other.qml文件中
Rectangle
{
Label{Text{text:“world”}} //Text属性自动成为Label的默认属性,等价于Label{someText:Text{text:“World”}}
}
7.必须属性
required property propertyType propertyName
Rectangle{required color} //颜色属性必须进行设置,不然报错
8.只读属性
//只读属性必须给出初始值 readonly property propertyType propertyName:value
9.属性修饰符
属性可以拥有关联的属性修饰符对象, propertyModifierTypeName on propertyName
// 常用于动画类型
Rectangle{
NumberAnimation on x {to:50;duration:1000}
}
信号和信号处理器特性
1.声明信号特性
signal signalName() ,如果信号没有参数,括号可以省略,有参数,则必须声明
例子:
Rectangle{
signal clicked
signal actionPed(action:string,res: var) //参数action res string和var是参数类型
}
2.属性改变信号
属性值改变时会默认有一个属性值改变信号触发,
property color nextColor
onNextColorChanged:
doSomething()
3.信号处理器
当信号被发射时,信号处理器会被qml引擎自动调用
信号处理器可以通过分配函数访问信号中的参数
方法一
onSignalName:functiong(x,y){
console.log(x+": "+y)
}
方法二
onSignalName:(x)=>console.log(x+": "+y)
onSignalName:(_,y)=>console.log(": "+y) //只访问第二个参数,不访问第一个
4.connections类型
用于连接外部对象的信号
例子:
Rectangle
{
id:rect
MouseArea{
id:mouseArea
anchors.fill: parent
//信号处理器触发
onClicked: console.log(“mouseArea”)
}
//使用Connections连接mouseArea的clicked信号,通过信号处理器onClicked触发
Connections{
function onClicked(){rect.color = “red”}
target: mouseArea
}
//通过connect将信号msgRecved与函数func1、func2、func3链接
signal msgRecved(string per,string pos)
signal customSend()
Component.onCompleted:{
rect.msgRecved.connect(func1)
rect.msgRecved.connect(func2)
rect.msgRecved.connect(func3)
mouseArea.clicked.connect(customSend) //信号连接信号
}
function func1(per,pos){}
function func2(per,pos){}
function func3(per,pos){}
}
5.方法特性
类似于槽函数
function functionName(param....)
Rectangle{id:rect
function calc():real{return rect.width/2}
width:400;height:calc()
}
6.附加属性和附加信号处理器
ListView
{
delegate:Rectangle{
width:100;height:100
color:ListView.isCurrentItem?"red":"blue" //附加类型的名称是ListView,附加相关的属性是isCurrentItem
}
}
ListView
{
width:100;height:100
model:ListModel{
id:ListModel
Component.onCompleted{ //Component.onCompleted就是一个附加信号处理器
for(var i =0;i<10;i++){
ListModel.append({"name":"Item"+i})
}
}
delegate:Text{text:index+" "+Name}
}
}
集成JavaScript
1.使用binding()绑定js
Rectangle{
keys.onSpacePressed:height= width3 //直接绑定
keys.onSpacePressed:height=Qt.binding(function(){return width3}) //动态绑定,执行了某个事情后重新对属性height进行一个新的绑定
}
2.自定义函数
Rectangle{
function factor(a){return (a<=1)?1:(a*factor(a-1))}
MouseArea{
anchors.fill:parent
onClicked:console.log(factor(10))
}
}
3.导入javascript文件中的函数
//假设XXX.js文件中有个factor函数
import “XXX.js” as MaFunc
Rectangle{
MouseArea{
anchors.fill:parent
onClicked:console.log(MaFunc.factor(10))
}
}
4.关联信号和js函数
import “XXX.js” as MaFunc
Rectangle{
MouseArea{
id:mouseArea
anchors.fill:parent
}
Component.onCompleted{mouseArea.clicked.connect(MaFunc.factor(10))}
}
5.启动时运行js函数
import “XXX.js” as MaFunc
Rectangle{
function startFucn(){ }
Component.onCompleted{
startFucn()
}
}
6.从js中动态创建QML对象
6.1 Qt.createComponent() 创建一个Component对象,适用于从QML文档中使用定义的组件,动态创建该组件
例子:
XX.qml文件定义了一个Rectangle组件
Rectangle{width:80;height:80;color:"red"}
componentCCreate.js文件中的内容如下
var component;
var sprite;
function createSpriteObj(){
component=Qt.createCComponent("XX.qml");
if(component.status === Component.Ready)
finishCreate();
else
component.statusChanged.connect(finishCreate)
}
//安全处理
function finishCreate(){
if(component.status === Component.Ready){
sprite = component.createObject(appWindow,{x:100,"y:100"}); //sprite是appWindow的子对象
if(sprite === null){}
}
else if(component.status === Component.Error){
console.log("")
}
}
然后在主程序文件中main.qml 导入componentCCreate.js文件
import "componentCCreate.js" as ScriptJs
Rectangle{
id:appWindow
width:80;height:80;
Component.onCompleted{ScriptJs.createSpriteObj()}
}
6.2 Qt.createQmlObject() 从一个QML字符串中创建对象,适用于运行时产生的对象
const newObj=Qt.createQmlObject(
'import QtQuick;Rectangle{color:"red";width:100;height:100}',
parent,
filepath
)
7.共享js资源库
在js文件的头要声明 .progma library
例子:
在factor.js文件
var count=0;
function factor(a){(a>0)?a*factor(a-1):1;}
在main.qml中
import “factor.js” as faccFuncc
Text{
property int input:17
text:"aa "+faccFuncc.factor(input)
}
8.在js资源中进行导入
import * as MAthFunc from “XX.mjs”
例子:
在mm.qml文件中
import “script.mjs” as MySript
Item{
width:100;height:100;
MouseArea{
onClicked:{MySript.showFunc()}
}
}
在XX.mjs文件中
import {fator} from “factor.mjs”
export {fator}
export function showFunc(value){}
在factor.mjs
export function fator(a){
//…
}