1基本语法格式
类型 {
属性名: 值
属性名: 值
子对象 {
// 子对象属性
}
}
2注释
和正常c++用法相同
3导入语句
1批量导入
import "components"
直接导入这个目录下的所有.qml文件
2导入某一个qml文件
// 导入特定的 QML 文件
import "MyButton.qml" as MyButton
导入指定的qml文件并且使用as起了一个别名
这里的起别名很重要,如果导入的库名字和其他导入的名字相同,产生了冲突,起别名可以避免这种冲突
3导入模块和版本
// 导入模块和版本
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
模块 在QML中是一个封装单元,它包含:
一组相关的QML类型
JavaScript文件
资源文件(如图像、字体等)
C++插件(如果需要)
负责导入对应的功能模块,qt把一些功能类似的模块放到了一起,导入的时候直接导入所需要的模块类型,减少了手动添加头文件的问题
其次导入版本模块提供了可以选择的版本号,与普通的include不同的是,有了版本号就可以导入新旧两个版本的库,对于我们来说更好的明确了当前程序模块版本号,避免误用不同的版本库
这里我们也可以使用qmldir定义一个自己的qml复用库
4.id属性
作用:方便在同一个qml文件中进行控件的引用,是控件对象的一个标识符号
同时他可以在跨作用域进行对象的引用,十分方便,同时不容易出错,可以在槽函数中进行使用
Rectangle {
id: container
width: 500
height: 500
Component {
id: circleComponent
Rectangle {
width: 50
height: 50
radius: 25
color: "green"
}
}
MouseArea {
anchors.fill: parent
onClicked: {
// 动态创建圆并定位到点击位置
var circle = circleComponent.createObject(container)
circle.x = mouse.x - 25
circle.y = mouse.y - 25
// 稍后可以通过parent引用容器
circle.parent = container
}
}
}
5属性系统
作用:可以把程序中使用的变量进行一个捆绑,当一个变量发生变化的时候,其他的变量也会发生变化,如果其他的变量绑定到了一些ui控件或者信号槽中使用的时候就会更新ui控件,或者触发信号槽
1自动化触发槽函数和更新ui以及数据,以及双向的绑定
// 双向绑定示例
TextField {
text: questionModel.questionText // 从C++读取
// 当用户编辑时,写回C++
onTextChanged: {
if (text !== questionModel.questionText) {
questionModel.questionText = text
}
}
}
2.实现qml和c++代码的绑定
Q_PROPERTY(QString questionText READ questionText WRITE setQuestionText NOTIFY questionTextChanged)
声明的属性是questionText
读取这个属性的函数是questionText
写这个属性的函数是setQuestionText
当属性发生变化会发射的信号名称是questionTextChanged,这个信号是qml和c++的桥梁,当信号被检测到,qml才能知道属性改变了,进而更新属性对应的一些信息,比如ui还有其他值的一些计算更新
6信号和槽
作用:用于代码之间交互的解耦
1控件之间进行信号和槽的传递
1.1声明
signal customClicked(string message) // 自定义信号
1.2处理信号
onClicked: {
// 当点击时,发射自定义信号,并传递一个字符串
root.customClicked("Hello from CustomButton!")
}
在控件中直接处理或者
// 另一个地方连接这个信号
Connections {
target: customBtn // 指定信号源
onClicked: (buttonName) => { // 信号处理器
console.log("自定义按钮被点击:", buttonName)
// 这里可以访问父作用域的所有属性
}
1.3信号和槽的匹配规则
当某个对象发射一个信号时,我们可以通过定义一个信号处理器来响应这个信号。信号处理器的命名规则是
on<SignalName>
7.接入 JavaScript
作用:让qml可以进行一些复杂的运算
1.可以衔接使用c++书写的代码
2可以使用javascript的一些库
3.可以使用JavaScript 的文件
4.支持异步操作
8布局管理
1锚点,用来替代绝对坐标,表示控件之间的相对关系
cpp
锚点的基本概念
1. 七条锚线(Anchor Lines)
每个 QML 项目都有 7 条锚线:
left(左边)
right(右边)
top(上边)
bottom(下边)
horizontalCenter(水平中心)
verticalCenter(垂直中心)
baseline(基线,主要用于文本对齐)
2. 锚点属性
通过 anchors 属性对象访问:
qml
anchors.left: targetItem.right // 将左边锚定到目标项目的右边
anchors.top: parent.top // 将上边锚定到父容器的上边
2定位器 用来处理简单的位置关系,均匀排布
cpp
Column {
spacing: 10
Rectangle { width: 100; height: 50; color: "red" }
Rectangle { width: 100; height: 50; color: "green" }
Rectangle { width: 100; height: 50; color: "blue" }
}
3布局管理器 用来处理复杂的位置关系
cpp
ColumnLayout {
width: 200
height: 200
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 50
color: "red"
}
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "green"
}
}
9状态和转换以及动画
目的:进行平滑的视觉效果过渡
使用选择:需要多个属性进行变化的时候使用更灵活的状态转换进行组合使用
只是单一的属性变化的时候可以使用动画进行状态过渡
10常犯错误
1循环绑定,
1.1a需要b,b需要a
1.2a触发b,b触发a