1. 类型名称必须以大写字母开头
导入语法
一个QML文档可以在文件顶部具有一个或多个导入。导入可以是以下任意一项:
- 已注册类型的版本化名称空间(例如,通过插件)
- 在相对目录中包含qml类型定义的文件
- 一个JavaScript文件
各种import的通用形式如下:
import Namespace VersionMajor.VersionMinor
import Namespace VersionMajor.VersionMinor as SingletonTypeIdentifier
import "directory"
import "file.js" as ScriptIdentifier
例子:
import QtQuick 2.0
import QtQuick.LocalStorage 2.0 as Database
import "../privateComponents"
import "somefile.js" as Script
QML对象属性
QML对象类型属性类型集如下:
- the id attribute
- property attributes
- signal attributes
- signal handler attributes
- method attributes
- attached properties and attached signal handler attributes
- enumeration attributes
ID属性(特殊属性)
每种QML对象类型都只有一个id属性。此属性由语言本身提供,
id值
必须以小写字母或下划线开头,并且不能包含字母,数字和下划线以外的字符。
id必须唯一
id定义后不能通过属性赋值进行修改
import QtQuick 2.0
Column {
width: 200; height: 200
TextInput { id: myTextInput; text: "Hello World" }
Text { text: myTextInput.text }
}
属性的特性
一个属性的值可以被其他对象读取。通常,它也可以由另一个对象修改,除非特定的QML类型明确禁止特定属性使用。、
定义属性的特性
在C++中使用Q_PROPERTY进行定义后,会注册到QML类型系统中,还可以在QML文档中使用
[default] property <propertyType> <propertyName>
进行注册。这样,就可以属性值暴露给外部对象。
属性名称必须以小写字母开头,并且只能包含字母,数字和下划线。JavaScript保留字不是有效的属性名称。
声明自定义属性会隐式创建该属性的值更改信号以及名为on <PropertyName> Changed的关联信号处理程序,其中<PropertyName>是属性的名称,首字母大写。
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}
Item {
property int someNumber
property string someString
property url someUrl
}
QtQuick
模块提供了一些基本类型,因此除非导入模块,否则不能用作属性类型。
var基本类型是通用占位符类型,可以保存任何类型的值,包括列表和对象:
property var someNumber: 1.5
property var someString: "abc"
property var someBool: true
property var someList: [1, 2, "three", "four"]
property var someObject: Rectangle { width: 100; height: 100; color: "red" }
此外,任何QML对象类型(包括自定义类型)都可以用作属性类型。例如
property Item someItem
property Rectangle someRectangle
属性赋值
可以通过两种方式指定对象实例的属性值
- a value assignment on initialization (初始化)
- an imperative value assignment (命令行赋值)
初始化赋值方法
<propertyName> : <value>
定义属性时顺带赋值
[default] property <propertyType> <propertyName> : <value>
赋值示例
import QtQuick 2.0
Rectangle {
color: "red"
property color nextColor: "blue" // combined property declaration and initialization
}
命令行赋值,是使用javascript中进行赋值
[<objectId>.]<propertyName> = value
示例
import QtQuick 2.0
Rectangle {
id: rect
Component.onCompleted: {
rect.color = "red"
}
}
类型安全
属性是类型安全的。只能为属性分配与属性类型匹配的值
特殊属性类型
Object List Property Attributes
列表类型定义
[ <item 1>, <item 2>, ... ]
例:
import QtQuick 2.0
Item {
states: [
State { name: "loading" },
State { name: "running" },
State { name: "stopped" }
]
}
如果列表中只有一项,可以省略方括号
import QtQuick 2.0
Item {
states: State { name: "running" }
}
列表属性声明语法:
[default] property list<<objectType>> propertyName
声明加初始化语法
[default] property list<<objectType>> propertyName: <value>
例子
import QtQuick 2.0
Rectangle {
// declaration without initialization
property list<Rectangle> siblingRects
// declaration with initialization
property list<Rectangle> childRects: [
Rectangle { color: "red" },
Rectangle { color: "blue"}
]
}
如果声明一个值不是QML对象,需要使用var定义
分组属性
在某些情况下,属性包含一组逻辑的子属性属性。可以使用点符号(.)或组符号({})将这些子属性属性分配给它们。
例
Text {
//dot notation
font.pixelSize: 12
font.b: true
}
Text {
//group notation
font { pixelSize: 12; b: true }
}
属性别名
属性别名语法
[default] property alias <name>: <alias reference>
命名用限制:
1.只能引用在同一作用域的对象或对象属性
2.不能包含Js表达式
3.属性别名必须初始化
4.不能引用附加属性
5.不能引用深度为3或更大的层次结构内的属性
例
property alias color: myItem.myRect.border.color //超过3层,不能使用
Item {
id: myItem
property Rectangle myRect
}
property alias color: rectangle.border.color //命名用两级是可以的
Rectangle {
id: rectangle
}
例
// Button.qml
import QtQuick 2.0
Rectangle {
property alias buttonText: textItem.text //按钮就可以直接操作文本了
width: 100; height: 30; color: "yellow"
Text { id: textItem }
}
使用按钮如下:
Button { buttonText: "Click Me" }
属性别名注意事项
仅在组件完全初始化后才能激活别名
别名属性可能与现有属性具有相同的名称,从而有效覆盖现有属性。
例:
Rectangle {
id: coloredrectangle
property alias color: bluerectangle.color
color: "red"
Rectangle {
id: bluerectangle
color: "#1234ff"
}
Component.onCompleted: {
console.log (coloredrectangle.color) //prints "#1234ff"
setInternalColor()
console.log (coloredrectangle.color) //prints "#111111"
coloredrectangle.color = "#884646"
console.log (coloredrectangle.color) //prints #884646
}
//internal function that has access to internal properties
function setInternalColor() {
color = "#111111"
}
}
属性别名没有明确的类型,如果将为一个对象的ID指定别明,是不能使用别名掉用对象属性的
例
// MyItem.qml
Item {
property alias inner: innerItem
Item {
id: innerItem
property int extraProperty
}
}
// main.qml
MyItem {
inner.extraProperty: 5 // fails
}
如果别名组件是一个单独文件定义的对象的话,是可以使用别名访问属性的
// MainItem.qml
Item {
// Now you can access inner.extraProperty, as inner is now an ExtraItem
property alias inner: innerItem
ExtraItem {
id: innerItem
}
}
// ExtraItem.qml
Item {
property int extraProperty
}
默认属性
定义默认属性的语法
default property var someText
默认属性每个对象只能定义一个
默认对象不用再通过属性名进行赋值
// MyLabel.qml
import QtQuick 2.0
MyLabel {
default property var someText
text: "Hello, " + someText.text
}
//调用时没有使用someText:Text { text: "world!" },默认属性可省略someText:
MyLabel {
Text{ text: "world!" }
}
只读属性
只读属性语法:
readonly property <propertyType> <propertyName> : <initialValue>
初始化时必须为只读属性分配一个值。以后再也不能以任何方式进行赋值。
属性修改器对象
属性可以有属性值修改器对象和他们关联。声明关联到具体属性的修改器类型实例的语法如下:
<PropertyModifierTypeName> on <propertyName> {
// attributes of the object instance
}
信号属性
信号处理程序使用 on<Signal> 语法声明, <Signal> 是信号名,第一个字母大写。信号处理程序必须声明在触发该信号的对象的定义内,并且处理程序应该包含 JavaScript 代码块当信号处理程序被调用时执行。
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
}
定义信号属性
signal <signalName>[([<type> <parameter name>[, ...]])]
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
}
触发信号,像调用方法一样调用信号。信号被触发时任何信号相关的处理将被调用,处理程序可以使用信号已定义的参数访问各自的参数。
信号处理程序属性
// SquareButton.qml
Rectangle {
id: root
signal activated(real xPosition, real yPosition) //定义信号
signal deactivated //定义信号
property int side: 100
width: side; height: side
MouseArea {
anchors.fill: parent
onPressed: root.activated(mouse.x, mouse.y) //发送信号
onReleased: root.deactivated() //发送信号
}
}
// myapplication.qml //同一文件夹下接收信号并处理。
SquareButton {
onActivated: console.log("Activated at " + xPosition + "," + yPosition)
onDeactivated: console.log("Deactivated!")
}
属性改变信号的处理
属性改变的信号的处理程序使用语法 on<Property>Changed ,<Property> 是属性的名字并且第一个字母大写。
import QtQuick 2.0
TextInput {
text: "Change this!"
onTextChanged: console.log("Text has changed to:", text)
}
方法属性
对象类型的方法是一个可以被调用去执行一些处理或触发后续事件的函数。方法可以连接到信号以便信号被触发时它可以被自动调用。
定义方法属性
类型的方法定义,可以在C++中使用 Q_INVOKABLE 标注将被注册到QML类型系统的类的函数,或者注册该函数为类的 Q_SLOT 。使用如下的语法在QML文档内添加自定义方法到对象的声明:
function <functionName>([<parameterName>[, ...]]) { <body> }
方法定义:
import QtQuick 2.0
Rectangle {
id: rect
function calculateHeight() {
return rect.width / 2;
}
width: 100
height: calculateHeight()
}
方法使用:
import QtQuick 2.0
Item {
width: 200; height: 200
MouseArea {
anchors.fill: parent
onClicked: label.moveTo(mouse.x, mouse.y)
}
Text {
id: label
function moveTo(newX, newY) {
label.x = newX;
label.y = newY;
}
text: "Move me!"
}
}
附加属性和附加信号处理程序
附加属性和附加信号处理程序是一种使对象被解释为扩展属性或信号处理程序(否则无效)的机制,特别地,这允许对象访问与个别对象明确相关的属性或者信号。
语法:
<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>
示例
/*比如, ListView 类型有一个可被附加的属性 ListView.isCurrentItem 并且 ListView 内的每一个代理对象可使用(此附加属性)。这可以被每一个不同的代理对象用来确定自己是否是视图内当前被选中的元素。*/
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
}
访问附加属性和信号处理程序的注意事项
附加类型的实例仅仅附属于特定对象,不属于对象和它的所有子对象。
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Item {
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow" // WRONG! This won't work.
}
}
}
//以下是正确写法
ListView {
//....
delegate: Item {
id: delegateItem
width: 100; height: 30
Rectangle {
width: 100; height: 30
color: delegateItem.ListView.isCurrentItem ? "red" : "yellow" // correct
}
}
}
枚举属性
// MyText.qml
Text {
enum TextType {
Normal,
Heading
}
}
// 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
}
枚举属性只能在5.10以后使用