QML自定义属性和方法
在 QML 中,你可以通过 property
关键字定义自定义属性,并通过 JavaScript 函数定义自定义方法。下面是详细的实现方式:
自定义属性
基本语法
qml
property <type> <name>[: <default value>]
属性类型示例
qml
// 基本类型
property int counter: 0
property bool isActive: true
property string title: "Default Title"
property real pi: 3.14159
// 复杂类型
property url website: "https://qt.io"
property date currentDate: new Date()
property var dynamicData: {"key": "value"} // 通用类型
property list<Item> childItems // 列表类型
// 对象类型
property Rectangle rect: Rectangle { color: "red" }
property font textFont: Qt.font({ family: "Arial", pointSize: 12 })
// 只读属性
readonly property string version: "1.0.0"
// 属性别名
property alias innerText: textItem.text
Text { id: textItem }
自定义方法
基本语法
qml
function <name>(<parameters>) {
// 方法体
[return <value>;]
}
方法示例
qml
Item {
id: myItem
// 自定义属性
property int value: 0
// 简单方法
function increment() {
value++;
}
// 带参数的方法
function add(amount) {
value += amount;
}
// 带返回值的方法
function getSquare() {
return value * value;
}
// 使用外部属性的方法
function reset(newValue) {
if (newValue !== undefined) {
value = newValue;
} else {
value = 0;
}
}
// 调用其他方法
function doubleAndSquare() {
value *= 2;
return getSquare();
}
}
属性和方法的结合使用
qml
Rectangle {
id: customButton
// 自定义属性
property string buttonText: "Click Me"
property color buttonColor: "blue"
property int clickCount: 0
// 自定义方法
function click() {
clickCount++;
console.log("Button clicked", clickCount, "times");
return clickCount;
}
function setColor(newColor) {
if (Qt.colorEqual(newColor, buttonColor)) {
console.log("Same color");
return false;
}
buttonColor = newColor;
return true;
}
// 使用方法
MouseArea {
anchors.fill: parent
onClicked: {
parent.click();
parent.setColor(Qt.rgba(Math.random(), Math.random(), Math.random(), 1));
}
}
// 显示
width: 200; height: 50
color: buttonColor
Text {
text: buttonText + " (" + clickCount + ")"
anchors.centerIn: parent
}
}
高级用法
属性验证
qml
property int age: 18
onAgeChanged: {
if (age < 0) age = 0;
if (age > 120) age = 120;
}
私有方法约定
qml
// 以下划线开头表示私有方法(约定)
function _internalCalculation(x, y) {
return x * y + this.value;
}
信号与方法的结合
qml
Item {
id: processor
signal processingComplete(string result)
property var inputData
function process() {
// 模拟耗时处理
var result = _heavyProcessing(inputData);
processingComplete(result);
}
function _heavyProcessing(data) {
// 复杂处理逻辑
return "Processed: " + JSON.stringify(data);
}
}
使用场景示例
自定义可重用组件
qml
// ProgressIndicator.qml
Item {
id: root
property real progress: 0.0
property color fillColor: "green"
property color backgroundColor: "lightgray"
function reset() {
progress = 0.0;
}
function complete() {
progress = 1.0;
}
function increment(amount) {
progress = Math.min(1.0, progress + amount);
}
width: 200; height: 20
Rectangle {
anchors.fill: parent
color: root.backgroundColor
}
Rectangle {
width: parent.width * root.progress
height: parent.height
color: root.fillColor
}
}
使用方法
qml
ProgressIndicator {
id: progress
fillColor: "blue"
Timer {
interval: 100
running: true
repeat: true
onTriggered: {
progress.increment(0.01);
if (progress.progress >= 1.0) stop();
}
}
}
注意事项
-
方法名不要与现有属性或方法冲突
-
避免在方法中创建过多的临时对象
-
复杂逻辑考虑使用C++实现并通过QML调用
-
方法中的
this
指向当前QML对象 -
属性变化信号会自动生成(on<Property>Changed)
-
方法可以访问作用域内的所有属性和其他方法