一、QML 基础类型概述
QML Base Type 是 QML 语言内置的基本数据类型,不需要导入任何模块即可使用。它们是构建 QML 应用程序的基础。
见:https://doc-snapshots.qt.io/qt6-6.8/qmlvaluetypes.html
二、基本数据类型
2.1 bool - 布尔类型
javascript
property bool isActive: true
property bool isVisible: false
// 使用示例
Rectangle {
visible: isActive && isVisible
enabled: !isDisabled
}
2.2 int - 整数类型
javascript
property int count: 0
property int width: 100
property int height: 200
// 支持16进制
property int hexValue: 0xFF
property int binaryValue: 0b1010
property int octalValue: 0o77
// 使用示例
onCountChanged: {
console.log("Count changed to:", count)
console.log("Hex representation:", count.toString(16))
}
2.3 real - 浮点数类型
javascript
property real opacity: 0.5
property real scale: 1.0
property real rotation: 45.5
// 科学计数法
property real largeNumber: 1.23e5
property real smallNumber: 1.23e-5
// 使用示例
Behavior on opacity {
NumberAnimation { duration: 200 }
}
2.4 double - 双精度浮点
javascript
// 在QML中,real和double通常是等价的
property double precisionValue: 3.141592653589793
// 使用示例
function calculateCircleArea(radius: double) {
return Math.PI * radius * radius
}
2.5 string - 字符串类型
javascript
// 基本字符串
property string name: "Qt Quick"
property string emptyString: ""
property string nullString // 未定义,为null
// 多行字符串
property string multiline: "这是第一行
这是第二行
这是第三行"
// 转义字符
property string escaped: "包含引号:\"和换行符:\n和制表符:\t"
// 模板字符串
property string template: `当前值: ${count}, 最大值: ${maxValue}`
// 使用示例
Text {
text: name + " - " + version
font.family: "Microsoft YaHei"
// 字符串方法
Component.onCompleted: {
console.log("长度:", text.length)
console.log("大写:", text.toUpperCase())
console.log("小写:", text.toLowerCase())
console.log("包含?", text.includes("Qt"))
console.log("分割:", text.split(" "))
console.log("替换:", text.replace("Quick", "Fast"))
}
}
2.6 url - URL类型
javascript
// 各种URL格式
property url imageSource: "images/icon.png" // 相对路径
property url absolutePath: "file:///C:/Users/image.png" // 绝对路径
property url webUrl: "https://www.qt.io" // 网络URL
property url dataUrl: "data:text/html,<h1>Hello</h1>" // Data URL
// 使用示例
Image {
source: imageSource
sourceSize.width: 100
sourceSize.height: 100
// URL相关属性
onStatusChanged: {
if (status === Image.Ready) {
console.log("图片来源:", source)
console.log("是否本地文件?", source.toString().startsWith("file://"))
console.log("URL路径:", source.toString())
}
}
}
2.7 color - 颜色类型
javascript
// 各种颜色表示方式
property color redColor: "red" // 颜色名称
property color hexColor: "#FF0000" // 十六进制
property color hexShort: "#F00" // 短十六进制
property color rgbColor: "#FF0000FF" // 带透明度
property color qtColor: Qt.rgba(1.0, 0.0, 0.0, 1.0) // Qt.rgba
property color hslaColor: Qt.hsla(0.0, 1.0, 0.5, 1.0) // Qt.hsla
property color lighterRed: Qt.lighter("red", 1.5) // 更亮
property color darkerRed: Qt.darker("red", 1.5) // 更暗
property color alphaRed: Qt.rgba(1, 0, 0, 0.5) // 半透明
// 使用示例
Rectangle {
color: themeColor
// 颜色属性和方法
Component.onCompleted: {
console.log("红色分量:", color.r)
console.log("绿色分量:", color.g)
console.log("蓝色分量:", color.b)
console.log("透明度:", color.a)
console.log("HSL - 色相:", color.hslHue)
console.log("HSL - 饱和度:", color.hslSaturation)
console.log("HSL - 亮度:", color.hslLightness)
console.log("HSV - 色相:", color.hsvHue)
console.log("HSV - 饱和度:", color.hsvSaturation)
console.log("HSV - 亮度:", color.hsvValue)
// 修改颜色
var newColor = Qt.tint(color, "blue")
console.log("混合后的颜色:", newColor)
}
}
2.8 date - 日期时间类型
javascript
// 创建日期对象
property date currentDate: new Date()
property date specificDate: new Date(2024, 0, 1) // 2024年1月1日
property date fromString: new Date("2024-01-01T00:00:00")
property date fromTimestamp: new Date(1704067200000)
// 使用示例
Text {
text: Qt.formatDateTime(currentDate, "yyyy-MM-dd hh:mm:ss")
Component.onCompleted: {
var now = new Date()
// 获取日期组件
console.log("年份:", now.getFullYear())
console.log("月份(0-11):", now.getMonth())
console.log("日期:", now.getDate())
console.log("小时:", now.getHours())
console.log("分钟:", now.getMinutes())
console.log("秒:", now.getSeconds())
console.log("毫秒:", now.getMilliseconds())
console.log("星期几:", now.getDay())
console.log("时间戳:", now.getTime())
// 修改日期
var tomorrow = new Date(now)
tomorrow.setDate(now.getDate() + 1)
console.log("明天:", tomorrow.toLocaleDateString())
// 日期运算
var diff = tomorrow - now
console.log("相差毫秒数:", diff)
console.log("相差天数:", diff / (1000 * 60 * 60 * 24))
// 格式化
console.log("ISO格式:", now.toISOString())
console.log("本地字符串:", now.toLocaleString())
}
}
2.9 var - 通用类型
javascript
// var可以存储任何类型的值
property var dynamicValue // 未初始化时为undefined
// 存储不同类型的数据
property var numberValue: 42
property var stringValue: "Hello"
property var boolValue: true
property var arrayValue: [1, 2, 3, "four"]
property var objectValue: { "name": "Qt", "version": 6.5 }
property var functionValue: function(x) { return x * x }
property var nullValue: null
property var undefinedValue // 显式undefined
// 使用示例
Item {
Component.onCompleted: {
// 类型检查
console.log("类型检查:")
console.log("是否是数组?", Array.isArray(arrayValue))
console.log("是否是对象?", typeof objectValue === 'object' && objectValue !== null)
console.log("是否是函数?", typeof functionValue === 'function')
console.log("是否是null?", objectValue === null)
console.log("是否是undefined?", typeof undefinedValue === 'undefined')
// 访问数组
console.log("数组长度:", arrayValue.length)
console.log("第一个元素:", arrayValue[0])
// 访问对象
console.log("对象属性:", objectValue.name)
console.log("所有属性:", Object.keys(objectValue))
// 调用函数
console.log("函数调用:", functionValue(5))
// 类型转换
console.log("转换为字符串:", String(numberValue))
console.log("转换为数字:", Number("123"))
console.log("转换为布尔:", Boolean(""))
// JSON处理
var jsonStr = JSON.stringify(objectValue)
console.log("JSON字符串:", jsonStr)
var parsedObj = JSON.parse(jsonStr)
console.log("解析后的对象:", parsedObj)
}
}
三、Qt 全局对象
3.1 Qt 对象
javascript
// 平台和应用程序信息
property string platform: Qt.platform.os
property var application: Qt.application
// 创建对象
property var component: Qt.createComponent("MyComponent.qml")
property var qmlObject: Qt.createQmlObject(`
import QtQuick 2.0
Rectangle { color: "red"; width: 50; height: 50 }
`, parent, "dynamicObject")
// 实用函数
property point position: Qt.point(100, 100)
property size itemSize: Qt.size(200, 100)
property rect area: Qt.rect(0, 0, 400, 300)
property vector2d vec2: Qt.vector2d(1.0, 2.0)
property vector3d vec3: Qt.vector3d(1.0, 2.0, 3.0)
property vector4d vec4: Qt.vector4d(1.0, 2.0, 3.0, 4.0)
property quaternion quat: Qt.quaternion(1, 0, 0, 0)
property matrix4x4 matrix: Qt.matrix4x4()
// 使用示例
Item {
Component.onCompleted: {
console.log("=== Qt 对象功能 ===")
// 平台信息
console.log("操作系统:", Qt.platform.os)
console.log("应用名称:", Qt.application.name)
console.log("应用版本:", Qt.application.version)
console.log("应用状态:", Qt.application.state)
// 颜色函数
console.log("RGBA颜色:", Qt.rgba(0.5, 0.5, 0.5, 1.0))
console.log("HSLA颜色:", Qt.hsla(0.5, 1.0, 0.5, 1.0))
console.log("颜色混合:", Qt.colorEqual("red", "#FF0000"))
console.log("随机颜色:", Qt.rgba(Math.random(), Math.random(), Math.random(), 1))
// 几何函数
console.log("点:", Qt.point(10, 20))
console.log("大小:", Qt.size(100, 200))
console.log("矩形:", Qt.rect(0, 0, 300, 400))
// 向量运算
var v1 = Qt.vector2d(1, 2)
var v2 = Qt.vector2d(3, 4)
console.log("向量相加:", v1.plus(v2))
console.log("向量点积:", v1.dotProduct(v2))
console.log("向量长度:", v1.length())
console.log("标准化:", v1.normalized())
// 工具函数
console.log("绑定函数:", Qt.binding(function() { return width * 2 }))
console.log("调用延迟:", Qt.callLater(function() { console.log("延迟执行") }))
console.log("MD5哈希:", Qt.md5("Hello World"))
console.log("格式化日期:", Qt.formatDateTime(new Date(), "yyyy-MM-dd"))
console.log("格式化时间:", Qt.formatTime(new Date(), "hh:mm:ss"))
console.log("本地化数字:", Qt.locale().toCurrencyString(1234.56))
// 分辨率缩放
console.log("像素密度:", Qt.pixelDensity)
console.log("设备像素比:", Qt.devicePixelRatio)
// 枚举值
console.log("对齐方式 - 左对齐:", Qt.AlignLeft)
console.log("对齐方式 - 居中:", Qt.AlignHCenter)
console.log("鼠标按钮 - 左键:", Qt.LeftButton)
// 随机数
console.log("随机整数(1-10):", Qt.random(1, 10))
console.log("随机布尔值:", Math.random() > 0.5)
// URL处理
var url = "images/icon.png"
console.log("解析URL:", Qt.resolvedUrl(url))
console.log("URL转字符串:", Qt.url(url).toString())
}
}
四、列表和数组
4.1 list - 列表类型
javascript
// 定义列表
property list<Item> childItems
property list<Rectangle> rectangles
property list<string> names: ["Alice", "Bob", "Charlie"]
property list<int> numbers: [1, 2, 3, 4, 5]
property list<var> mixedList: [1, "two", true, {key: "value"}]
// 使用示例
Item {
// 添加元素到列表
Component.onCompleted: {
// 直接赋值(替换整个列表)
names = ["David", "Eve"]
// 使用JavaScript数组方法
names.push("Frank")
names.unshift("Zoe")
// 访问元素
console.log("第一个名字:", names[0])
console.log("列表长度:", names.length)
// 遍历列表
for (var i = 0; i < names.length; i++) {
console.log("名字", i, ":", names[i])
}
// 使用forEach
names.forEach(function(name, index) {
console.log(index + ": " + name)
})
// 数组方法
var filtered = names.filter(function(name) {
return name.length > 3
})
console.log("过滤后的名字:", filtered)
var mapped = names.map(function(name) {
return name.toUpperCase()
})
console.log("大写名字:", mapped)
// 查找
var index = names.indexOf("David")
console.log("David的索引:", index)
// 切片和拼接
var slice = names.slice(1, 3)
console.log("切片:", slice)
names.splice(1, 2, "George", "Helen")
console.log("拼接后的列表:", names)
}
// QML特有的列表操作
Repeater {
model: names
delegate: Text {
text: modelData
y: index * 20
}
}
}
五、枚举类型
5.1 enumeration - 枚举类型
javascript
// 自定义枚举
enum TextAlignment {
Left = Qt.AlignLeft,
Center = Qt.AlignHCenter,
Right = Qt.AlignRight
}
enum MessageType {
Info,
Warning,
Error,
Success
}
// 使用枚举
property enumeration alignment: TextAlignment.Center
property MessageType messageType: MessageType.Info
// 使用示例
Rectangle {
// 内置枚举示例
property int horizontalAlignment: Text.AlignHCenter
property int verticalAlignment: Text.AlignVCenter
// 鼠标按钮枚举
property int leftButton: Qt.LeftButton
property int rightButton: Qt.RightButton
property int middleButton: Qt.MiddleButton
// 键盘修饰键
property int shiftModifier: Qt.ShiftModifier
property int ctrlModifier: Qt.ControlModifier
property int altModifier: Qt.AltModifier
// 方向枚举
property int leftToRight: Qt.LeftToRight
property int rightToLeft: Qt.RightToLeft
Component.onCompleted: {
console.log("=== 枚举使用示例 ===")
// 自定义枚举
console.log("对齐方式:", alignment)
console.log("消息类型:", messageType)
// 枚举比较
if (messageType === MessageType.Info) {
console.log("这是一个信息消息")
}
// 枚举遍历(通过元对象系统)
console.log("所有对齐方式:")
for (var key in TextAlignment) {
console.log(key + " = " + TextAlignment[key])
}
// 内置枚举使用
console.log("文本水平对齐:", horizontalAlignment === Text.AlignHCenter ? "居中" : "其他")
console.log("鼠标左键值:", leftButton)
console.log("Shift键修饰符:", shiftModifier)
// 枚举组合(按位或)
var alignment = Qt.AlignHCenter | Qt.AlignVCenter
console.log("水平和垂直居中:", alignment)
// 检查枚举值
if (alignment & Qt.AlignHCenter) {
console.log("包含水平居中")
}
}
// 枚举在实际组件中的使用
Text {
id: sampleText
text: "示例文本"
horizontalAlignment: parent.horizontalAlignment
verticalAlignment: parent.verticalAlignment
// 使用枚举作为信号参数
signal textClicked(int mouseButton)
MouseArea {
anchors.fill: parent
onClicked: (mouse) => {
if (mouse.button === Qt.LeftButton) {
sampleText.textClicked(Qt.LeftButton)
} else if (mouse.button === Qt.RightButton) {
sampleText.textClicked(Qt.RightButton)
}
}
}
}
}
六、特殊类型
6.1 font - 字体类型
javascript
// 字体属性
property font customFont: Qt.font({
family: "Microsoft YaHei",
pointSize: 12,
weight: Font.Normal,
italic: false,
bold: false,
capitalization: Font.MixedCase
})
// 使用示例
Text {
text: "字体示例"
// 直接设置字体属性
font.family: "Arial"
font.pointSize: 14
font.weight: Font.Bold
font.italic: true
font.underline: true
font.strikeout: false
font.letterSpacing: 1.5
font.wordSpacing: 2.0
font.capitalization: Font.AllUppercase
Component.onCompleted: {
console.log("=== 字体信息 ===")
console.log("字体族:", font.family)
console.log("字号:", font.pointSize)
console.log("像素大小:", font.pixelSize)
console.log("字重:", font.weight)
console.log("是否粗体:", font.bold)
console.log("是否斜体:", font.italic)
console.log("是否下划线:", font.underline)
console.log("是否删除线:", font.strikeout)
console.log("字母间距:", font.letterSpacing)
console.log("单词间距:", font.wordSpacing)
console.log("大写模式:", font.capitalization)
// 系统字体
console.log("默认字体:", Qt.application.font.family)
console.log("默认字号:", Qt.application.font.pointSize)
// 字体度量
var metrics = Qt.createQmlObject(`
import QtQuick 2.0
TextMetrics {
font: parent.font
text: parent.text
}
`, this)
console.log("文本宽度:", metrics.width)
console.log("文本高度:", metrics.height)
console.log("文本上边距:", metrics.boundingRect.y)
}
}
6.2 其他内置类型
javascript
// 点类型
property point mousePosition
property point centerPoint: Qt.point(width/2, height/2)
// 大小类型
property size itemSize
property size minimumSize: Qt.size(100, 50)
// 矩形类型
property rect viewport
property rect boundingRect: Qt.rect(0, 0, width, height)
// 使用示例
Item {
width: 400
height: 300
Component.onCompleted: {
console.log("=== 几何类型 ===")
// 点操作
var p1 = Qt.point(10, 20)
var p2 = Qt.point(30, 40)
console.log("点1:", p1.x, p1.y)
console.log("点2:", p2.x, p2.y)
console.log("点相加:", p1.x + p2.x, p1.y + p2.y)
console.log("点相减:", p1.x - p2.x, p1.y - p2.y)
console.log("点相乘:", p1.x * p2.x, p1.y * p2.y)
// 大小操作
var s1 = Qt.size(100, 200)
var s2 = Qt.size(50, 75)
console.log("大小1:", s1.width, s1.height)
console.log("大小2:", s2.width, s2.height)
console.log("大小相加:", s1.width + s2.width, s1.height + s2.height)
console.log("大小缩放:", s1.width * 1.5, s1.height * 1.5)
console.log("宽高比:", s1.width / s1.height)
// 矩形操作
var rect = Qt.rect(10, 10, 100, 50)
console.log("矩形:", rect.x, rect.y, rect.width, rect.height)
console.log("左边界:", rect.left)
console.log("右边界:", rect.right)
console.log("上边界:", rect.top)
console.log("下边界:", rect.bottom)
console.log("中心点:", rect.center.x, rect.center.y)
console.log("矩形面积:", rect.width * rect.height)
// 矩形是否包含点
var testPoint = Qt.point(50, 30)
console.log("点是否在矩形内:", rect.contains(testPoint))
// 矩形相交
var rect2 = Qt.rect(50, 30, 80, 40)
console.log("矩形是否相交:", rect.intersects(rect2))
if (rect.intersects(rect2)) {
var intersection = rect.intersected(rect2)
console.log("相交区域:", intersection)
}
// 矩形合并
var union = rect.united(rect2)
console.log("合并后的矩形:", union)
}
}
七、类型转换和检查
javascript
Item {
Component.onCompleted: {
console.log("=== 类型转换和检查 ===")
// 类型检查
var value = 123
console.log("类型检查:")
console.log("是否是数字?", typeof value === 'number')
console.log("是否是整数?", Number.isInteger(value))
console.log("是否是有限数?", Number.isFinite(value))
console.log("是否是NaN?", isNaN(value))
// 类型转换
console.log("\n类型转换:")
console.log("转换为字符串:", String(value))
console.log("转换为数字:", Number("123.45"))
console.log("转换为整数:", parseInt("123.45"))
console.log("转换为浮点数:", parseFloat("123.45"))
console.log("转换为布尔:", Boolean(value))
// 严格类型转换
console.log("\n严格转换:")
console.log("字符串转整数(10进制):", parseInt("10", 10))
console.log("字符串转整数(16进制):", parseInt("FF", 16))
console.log("字符串转整数(2进制):", parseInt("1010", 2))
// 数值格式化
console.log("\n数值格式化:")
console.log("固定小数位:", (123.456).toFixed(2))
console.log("指数表示:", (123456).toExponential(2))
console.log("保留有效数字:", (123.456).toPrecision(4))
console.log("本地化数字:", (1234.56).toLocaleString())
// 颜色转换
console.log("\n颜色转换:")
var color = "red"
console.log("颜色转字符串:", color.toString())
console.log("是否有效颜色?", Qt.color(color).valid)
// 日期转换
console.log("\n日期转换:")
var dateStr = "2024-01-01"
var dateObj = new Date(dateStr)
console.log("字符串转日期:", dateObj)
console.log("日期转时间戳:", dateObj.getTime())
console.log("日期转ISO字符串:", dateObj.toISOString())
// 数组转换
console.log("\n数组转换:")
var array = [1, 2, 3]
console.log("数组转字符串:", array.toString())
console.log("数组转逗号分隔:", array.join(","))
console.log("数组转自定义分隔:", array.join(" - "))
// JSON转换
console.log("\nJSON转换:")
var obj = { name: "Qt", version: 6.5 }
var jsonStr = JSON.stringify(obj)
console.log("对象转JSON:", jsonStr)
var parsedObj = JSON.parse(jsonStr)
console.log("JSON转对象:", parsedObj)
// 安全类型转换
console.log("\n安全类型转换:")
function safeParseInt(str, defaultValue = 0) {
const num = parseInt(str, 10)
return isNaN(num) ? defaultValue : num
}
console.log("安全转换数字:", safeParseInt("123"))
console.log("安全转换无效数字:", safeParseInt("abc", 100))
// 类型判断最佳实践
console.log("\n类型判断最佳实践:")
function getType(value) {
if (value === null) return "null"
if (value === undefined) return "undefined"
if (Array.isArray(value)) return "array"
return typeof value
}
console.log("null的类型:", getType(null))
console.log("数组的类型:", getType([1, 2, 3]))
console.log("对象的类型:", getType({}))
console.log("函数的类型:", getType(function() {}))
}
}
这些基础类型是 QML 编程的基础,熟练掌握它们对于编写高效、可靠的 QML 应用程序至关重要。