QT中QML学习笔记2
- 默认属性:对象定义可以具有单个default属性,指在另一个对象的定义中声明某个对象而未将其声明为特定属性的值时为其赋值的属性。
使用optional关键字声明属性可将其标记为默认属性。例如:
// MyLabel.qml
import QtQuick
Text {
default property var someText //someText具有默认属性
text: `Hello, ${someText.text}`
}
//该值可在对象定义中赋值
MyLabel{
Text{text:"world!"}
}
//等价于
MyLabel{
someText:Text{text:"world!"}
}
- 必需属性:对象声明可以使用关键字根据需要定义属性。语法为required:
required property
以下自定义Rectangle组件,始终需要指定color属性:
Rectangle {
required color
}
//注意:不能从QML为required属性分配初始值,因为会直接违背其属性的预期用途
- 只读属性:对象声明可以使用关键字定义只读属性,语法如下:readonly
readonly property :
注意:初始化时,必须为只读属性分配静态值或绑定表法式。初始化只读属性后将无法更改其静态值或绑定表达式。
Property Modifier 对象:属性可具有与之关联的属性值修饰符对象。声明与特定属性关联的属性修饰符类型实例语法如下:
on {
// attributes of the object instance
} - 信号属性:信号是来自对象的通知,表明发生了某些事件:如属性更改,动画已启动或停止,下载图像等 当发出特定信号时,可以通过signal
handler通知对象。信号处理程序使用语法on声明,其中是信号的名称,第一个字母大写。必须在发出信号的对象定义中声明信号处理程序且处理程序应包含调用信号处理程序时要执行的javascript代码块:
例如:onClicked信号处理程序在对象定义中声明并在单击时调用,打印控制台信息:
import QtQuick
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}//点击鼠标控制台输出信息
}
}
- 定义信号属性:可通过注册类为C++中的类型定义信号,然后向QML类型系统注册;或可使用以下语法在QML文档的对象声明中定义对象类型的自定义信号:
signal [([: [, …]])]
//信号声明
import QtQuick
Item {
signal clicked//信号无参数可不使用()
signal hovered()
signal actionPerformed(action: string, actionResult: int)
}
- 信号处理程序属性:信号处理程序是一种特殊的方法属性,每当发出相关信号时,QML引擎会调用方法实现,默认情况下该对象定义具有空实现。客户端可提供implementation以实现程序逻辑:
//考虑以下类型,其定义在文件中提供,如下所示,其中包含 signals 和 :SquareButtonSquareButton.qmlactivateddeactivated
// SquareButton.qml
Rectangle {
id: root
signal activated(xPosition: real, yPosition: real)
signal deactivated
property int side: 100
width: side; height: side
MouseArea {
anchors.fill: parent
onReleased: root.deactivated()
onPressed: mouse => root.activated(mouse.x, mouse.y)
}
}
//信号处理程序的实现:SquareButton
// myapplication.qml
SquareButton {
onDeactivated: console.log("Deactivated!")
onActivated: (xPosition, yPosition) => {
console.log(`Activated at ${xPosition}, ${yPosition}`)
}
}
- 属性更改信号处理程序:采用语法形式onChanged,编写一个信号处理程序以便此属性更改时调用:textChangedonTextChanged
import QtQuick
TextInput {
text: "Change this!"
onTextChanged: console.log(`Text has changed to: ${text}`)
}
8.函数属性:对象类型的方法是可以调用以执行某些处理或触发更多事件的函数。方法可以连接到信号,以便在发出信号时自动调用该方法。
9.定义函数属性:通过标记一个类的函数来为一个类型定义一个方法,该函数随后被注册到QML类型系统中,或者将其注册为该类的一个;也可使用以下语法将自定义方法添加到QML文档中的对象声明中:
function ([[: ][, …]]) [: ] { }
注意:与signal不同,方法参数类型不必声明因为它们默认为该类型,但应该声明以帮助生成性能更高的代码并提高可维护性
10. 在分配值时调用的方法:calculateHeight()height
import QtQuick
Rectangle {
id: rect
function calculateHeight(): real {
return rect.width / 2;
}//无参函数
width: 100
height: calculateHeight()
}
11.如果函数有参数则可以在方法中按名称访问这些参数:
import QtQuick
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: mouse => label.moveTo(mouse.x, mouse.y)
}//点击时唤醒函数可重定位至此text中moveto的新的newX和newY
Text {
id: label
function moveTo(newX: real, newY: real) {
label.x = newX;
label.y = newY;
}
text: "Move me!"
}
}
12.附加属性和附加信号处理程序:使对象能够使用额外的属性或信号处理程序进行注释,引用语法:
.
.on
例如:
//该类型具有一个附加属性,可用于每个单独的代理对象都可使用其来确定是否时视图中的当前选定项
import QtQuick
ListView {
width: 240; height: 320
model: 3
delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"//附加属性
}
}
import QtQuick
ListView {
width: 240; height: 320
model: ListModel {
id: listModel
Component.onCompleted: {
for (let i = 0; i < 10; i++) {
append({ Name: `Item ${i}` })
}
}//附加的信号处理程序:Component.onCompleted
}
delegate: Text { text: index }
}
假设附加的属性和信号处理程序可以从这些属性已附加到的对象的子对象直接访问时错误的,attaching类型实例仅附加到特定对象而不附加到对象及其所有子对象:
import QtQuick
ListView {
width: 240; height: 320
model: 3
delegate: Item {
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow" // 这是错误的,它仅附加到根委托对象而不是子对象
}
}
}
//-----------------------------------------------------------
ListView {
delegate: Item {
**id: delegateItem**//特定对象
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // 这是正确的
}
}
}
13.枚举属性:枚举提供一组固定的命名选项,可使用enum关键字在QML中声明,枚举类型和值必须以大写字母开头:
// MyText.qml
Text {
enum TextType {
Normal,
Heading
}
property int textType: MyText.TextType.Normal
font.bold: textType === MyText.TextType.Heading
font.pixelSize: textType === MyText.TextType.Heading ? 24 : 12
}