最近学习QML和大家分享一下。(主要介绍QML对象特性)
QML是一种专门用于构建用户界面的编程语言,它允许开发人员和设计者构建高性能的、具有流畅动画特效的可视化应用程序。QML文档是高度可读的、声明式的文档,具有类似JSON的语法,支持使用JavaScript表达式,具有动态属性绑定等特性。
先来看这样一段代码
import QtQuick 2.2
Rectangle {
width: 400
height: 400
color: "blue"
Image {
source: "pics/logo.png"
anchors.centerIn: parent
}
}
其中import语句导入了QtQuick模块,它包含各种QML类型,如果没有import语句,后面的Rectangle和Image类型就无法使用。
代码中创建了两个对象,分别是Rectangle和Image,他们以大写字母开头,后面跟着一对大括号。括号中是对对象属性的定义与赋值,还有子对象的定义。
最后一行表示Image处于其父对象Rectangle的中心。
代码运行结果如下:
下面介绍一下QML的对象特性
每一个QML对象在创建时都会包含一组特性,这些特性是在该对象中定义的。一个QML文档中的对象声明定义了一个新的类型,其中可以包含如下特性:id特性、属性(property)特性、信号(signal)特性、信号处理器(signal handler)特性、方法(method)特性、附加属性和附加信号处理器特性。
1、Id特性
每一个对象都可以指定一个唯一的id,这样便可以在其他对象中识别并引用该对象。Id值在一个组件(component)的作用域中必须是唯一的。
import QtQuick 2.2
Row {
Text {
id: text1
text: "Hello World"
}
Text { text: text1.text }
}
代码中有两个text对象,对一个text对象的id是text1,第二个text对象的text属性是用text1的text属性定义的。我们无法使用test1.id来获得id特性,一旦对象被创建,它的id就无法改变。线之外的字符。
2、属性特性
属性是对象的一个特性,可以分配一个静态的值,也可以绑定一个动态表达式。属性的值可以被其他对象读取和修改。
定义一个属性:
[default] property <propertyType> <propertyName>
注:id值必须使用小写字母或者下划线开头,并且不能使用字母、数字和下划
import QtQuick 2.2
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
nextColor: "red"
MouseArea {
anchors.fill:parent
onClicked: nextColor = "yellow"
}
}
代码中定义了两个新属性previousColor和nextColor,同时增加了一个信号处理器onNextColorChanged。实现了鼠标点击父窗口任意位置,控制台输出nextColor的变化。
运行后QML Scene中显示:
Starting C:\Qt\Qt5.7.0\5.7\mingw53_32\bin\qmlscene.exe...
qml: The next color will be: #ffff00
2.1 属性别名
属性别名类似C++的引用,它不需要分配一个新的存储空间,而是将新声明的属性作为一个已经存在的属性的直接引用。
定义属性别名:
[default] property alias <name> : <alias reference>
//Button.qml
import QtQuick 2.2
Rectangle {
property alias buttonText: textItem.text
width: 100; height: 30; color: "yellow"
Text { id: textItem }
}
代码中定义了一个Button类型,其有一个buttonText的属性别名,指向其Text子对象的text属性。在其他QML文档中使用Button类型时,可以直接使用如下语句定义其Text子对象的文本:
Button { buttonText: “click Me”};
注意:属性别名在整个组件初始化完毕之后才可以使用;属性别名可以与现有的属性同名,但会覆盖现有属性。
3、信号和信号处理器特性
信号是发出事件(如属性更改、动画状态变化、图片下载完成等)的对象发射的通知。特定的信号发射后,可以通过相应的信号处理器获得通知。
import QtQuick 2.2
Rectangle {
id: rect
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
rect.color = Qt.rgba(Math.random(),
Math.random(), Math.random(), 1);
}
}
}
代码实现了鼠标点击Rectangle对象时,其颜色会随机变化。
定义信号特性:
Signal <signalName> (<type> <parameterName>, …)
信号处理器
信号处理器是一类特殊的方法特性。当对应的信号发射时,信号处理器会被QML引擎自动调用。
//SquareButton.qml
import QtQuick 2.2
Rectangle {
id: root
signal activated(real xPosition, real yPosition)
signal deactivated
width: 100; height: 100
MouseArea {
anchors.fill: parent
onPressed: root.activated(mouse.x, mouse.y)
onReleased: root.deactivated()
}
}
代码中定义了两个信号activated和deactivated。这些信号可以被与SquareButton.qml同目录下的其他QML文件接收。
//myapplication.qml
import QtQuick 2.2
SquareButton {
onActivated: console.log("Activated at "
+ xPosition + "," + yPosition)
onDeactivated: console.log("Deactivated!")
}
一个信号与多个方法相关联使用connect()函数。
import QtQuick 2.2
Rectangle {
id: relay
signal messageReceived(string person, string notice)
Component.onCompleted: {
relay.messageReceived.connect(sendToPost)
relay.messageReceived.connect(sendToTelegraph)
relay.messageReceived.connect(sendToEmail)
relay.messageReceived("Tom", "Happy Birthday")
}
function sendToPost(person, notice) {
console.log("Sending to post: " + person + ", " + notice)
}
function sendToTelegraph(person, notice) {
console.log("Sending to telegraph: " + person + ", " + notice)
}
function sendToEmail(person, notice) {
console.log("Sending to email: " + person + ", " + notice)
}
}
将信号与动态创建的对象关联起来同样需要使用connect()函数。
import QtQuick 2.2
Rectangle {
id: forwarder
width: 100; height: 100
signal send()
onSend: console.log("Send clicked")
MouseArea {
id: mousearea
anchors.fill: parent
onClicked: console.log("MouseArea clicked")
}
Component.onCompleted: {
mousearea.clicked.connect(send)
}
}
当MouseArea发出clicked信号时,自定义的send信号也会被自动发射。
4、方法特性
对象的方法就是一个函数,可以执行某些处理或者触发其他事件。我们可以将方法关联到信号上,这样在发射该信号时就会自动调用该方法。
自定义方法:
Function <functionName> (<parameterName>,…) {<body>}
QML的方法可以用于定义相对独立的可重用的JavaScript代码块。这些方法可以在内部调用,也可以被外部对象调用。
import QtQuick 2.2
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: label.moveTo(mouse.x, mouse.y)
}
Text {
id: label; text: "Move me!"
function moveTo(newX, newY) {
label.x = newX;
label.y = newY;
}
}
}
代码运行后,label会随鼠标的移动而移动。
5、附加属性和附加属性信号处理器
附加属性和附加属性信号处理器是一种允许对象使用额外的属性或信号处理器的机制,如果没有这种机制,这些属性或信号处理器就无法应用于这个对象。
语法:
<ArrachingType>.<propertyName>
<ArrachingType>.on<SignalName>
附加属性
import QtQuick 2.2
ListView {
width: 240; height: 320; model: 3; focus: true
delegate: Rectangle {
width: 240; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
}
代码运行后,
移动上下方向键,选择条目颜色变化。
至此,有关QML对象特性的内容就介绍完了。