一、前言
上一次我们搭建好了MacOS下的Qt6+Android开发环境,而且创建了简单的helloworld项目进行测试,官方是强烈推荐qml进行开发的,我试了一下确实还可以,但是由于是新手,虽然有一些js和前端的基础,但是还是感觉Qt crearot以及qml写起来不顺手,主要还是新手不熟悉控件的相关属性,导致写起来不畅快,然后正好在掘金发现了AI IDE工具Trae,我初步试了下确实很不错,新手对于一些控件不熟悉也可以快速补全,相当于vscode+代码智能补全+deepseek,确实写起来代码很流畅,这里正好借着学习qml开发Android程序的过程来使用一下。
二、qml实现常用控件
直接在trae上问常见的控件,然后我们一个个再来熟悉和实践:
1. 窗口控件
- Window:代表一个顶级窗口,可用于创建应用程序的主窗口。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
width: 320
height: 720
visible: true
title: qsTr("Hello World")
}
在 QML 中,窗口控件(如 Window)有许多常见的属性可以设置,下面为你介绍一些常用属性及其示例:
1.1. 尺寸属性
width** 和 **height:用于设置窗口的宽度和高度,单位为像素。- 注意:width 和 height 属性使用的单位是像素(px),而非设备独立像素(dp)。所以 width: 320 和 height: 720 代表的是 320 像素和 720 像素,所以结合设计图时要注意这一点。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
width: 400
height: 600
// ... existing code ...
}
1.2. 可见性属性
visible:用于控制窗口是否可见,值为true或false。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
visible: true
// ... existing code ...
}
1.3. 标题属性
title:用于设置窗口的标题,值为字符串。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
title: qsTr("新的窗口标题")
// ... existing code ...
}
1.4. 背景颜色属性
color:用于设置窗口的背景颜色,可以使用颜色名称、十六进制值等。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
color: "lightblue"
// ... existing code ...
}
1.5. 最小和最大尺寸属性
minimumWidth、minimumHeight、maximumWidth** 和 **maximumHeight:用于设置窗口的最小和最大宽度、高度。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
minimumWidth: 200
minimumHeight: 300
maximumWidth: 800
maximumHeight: 600
// ... existing code ...
}
1.6. 模态属性
modality:用于设置窗口的模态行为,控制窗口是否阻塞其他窗口的输入。常见值有Qt.NonModal(非模态)、Qt.WindowModal(窗口模态)和Qt.ApplicationModal(应用程序模态)。
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick 2.12
Window {
// ... existing code ...
modality: Qt.WindowModal
// ... existing code ...
}
1.7. 测试效果
写注释都有AI提示:(投屏的使用scrcpy,brew install scrcpy安装即可)
2. 文本控件
- Text:用于显示静态文本。
Text {
text: "这是一段文本"
font.pixelSize: 20
color: "red"
}
在 QML 里,文本控件(Text)有许多常见属性,下面为你详细介绍:
2.1. 文本内容属性
text:用于设置或获取文本控件显示的内容。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
Text {
text: "这是一段文本"
}
// ... existing code ...
}
2.2. 字体属性
font.family:设置字体名称。font.pixelSize:设置字体大小,单位为像素。font.bold:设置字体是否加粗,值为true或false。font.italic:设置字体是否倾斜,值为true或false。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
Text {
text: "自定义字体文本"
font.family: "Arial"
font.pixelSize: 20
font.bold: true
font.italic: true
}
// ... existing code ...
}
2.3. 颜色属性
color:设置文本的颜色,可以使用颜色名称、十六进制值等。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
Text {
text: "红色文本"
color: "red"
}
// ... existing code ...
}
2.4. 对齐属性
horizontalAlignment:设置文本的水平对齐方式,常见值有Text.AlignLeft、Text.AlignHCenter、Text.AlignRight等。verticalAlignment:设置文本的垂直对齐方式,常见值有Text.AlignTop、Text.AlignVCenter、Text.AlignBottom等。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
Text {
text: "居中对齐文本"
width: 200
height: 50
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
// ... existing code ...
}
2.5. 换行属性
wrapMode:设置文本的换行模式,常见值有Text.NoWrap(不换行)、Text.WordWrap(按单词换行)等。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
Text {
text: "这是一段很长的文本,可能需要换行显示。"
width: 100
wrapMode: Text.WordWrap
}
// ... existing code ...
}
2.6. 可见性属性
visible:控制文本控件是否可见,值为true或false。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
// ... existing code ...
Text {
text: "隐藏或显示的文本"
visible: false
}
// ... existing code ...
}
2.7. 测试效果
3. 按钮控件
注意:按钮需要导入如下模块
import QtQuick.Controls 2.12
- Button:可点击的按钮,通常用于触发操作。
import QtQuick.Controls 2.12
Button {
text: "点击我"
onClicked: {
console.log("按钮被点击了")
}
}
在 QML 里,按钮控件(通常使用 Button 组件,需导入 QtQuick.Controls 模块)有许多常见属性,下面为你详细介绍并给出示例:
3.1. 文本属性
text:用于设置按钮上显示的文本内容。
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
// ... existing code ...
Button {
text: "点击我"
}
// ... existing code ...
3.2. 尺寸属性
width** 和 **height:用于设置按钮的宽度和高度。
// ... existing code ...
Button {
text: "自定义尺寸按钮"
width: 150
height: 50
}
// ... existing code ...
3.3. 状态属性
enabled:控制按钮是否可用,值为true或false。当设置为false时,按钮不可点击。pressed:表示按钮是否被按下,通常用于监听按钮按下和释放的状态变化。
// ... existing code ...
Button {
text: "禁用按钮"
enabled: false
}
Button {
text: "状态监听按钮"
onPressed: console.log("按钮被按下")
onReleased: console.log("按钮被释放")
}
// ... existing code ...
3.4. 样式属性
background:用于自定义按钮的背景,可以使用Rectangle等组件。contentItem:用于自定义按钮的内容,例如文本、图标等。
// ... existing code ...
Button {
width: 100
height: 40
background: Rectangle {
color: pressed ? "gray" : "blue"
radius: 5
}
contentItem: Text {
text: parent.text
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
// ... existing code ...
3.5. 信号与槽属性
onClicked:按钮被点击时触发的信号,可关联相应的处理函数。
// ... existing code ...
Button {
text: "触发事件按钮"
onClicked: {
console.log("按钮被点击,执行相应操作")
// 可以在这里添加其他操作
}
}
// ... existing code ...
3.6. 测试效果
4. 输入控件
- TextField:单行文本输入框。
import QtQuick.Controls 2.12
TextField {
placeholderText: "请输入文本"
onTextChanged: {
console.log("输入的文本是: " + text)
}
}
- TextArea:多行文本输入框。
import QtQuick.Controls 2.12
TextArea {
placeholderText: "请输入多行文本"
width: 200
height: 100
}
在 QML 里,常见的输入控件有 TextField(单行输入框)和 TextArea(多行输入框),下面为你详细介绍它们的常用属性。
4.1. TextField 常用属性
文本内容相关
text:用于设置或获取输入框当前的文本内容。placeholderText:当输入框为空时显示的提示文本。
// ... existing code ...
TextField {
id: singleInput
text: "默认文本"
placeholderText: "请输入内容"
}
// ... existing code ...
输入显示相关
echoMode:控制文本的显示模式,常见值有TextField.Normal(正常显示)、TextField.Password(密码模式,显示星号)等。
// ... existing code ...
TextField {
id: passwordInput
echoMode: TextField.Password
placeholderText: "请输入密码"
}
// ... existing code ...
输入验证相关
validator:用于限制输入的内容,可使用IntValidator、DoubleValidator或RegExpValidator等。
// ... existing code ...
TextField {
id: numberInput
validator: IntValidator {
bottom: 0
top: 100
}
placeholderText: "请输入 0 - 100 之间的整数"
}
// ... existing code ...
信号相关
onTextChanged:当输入框的文本内容发生变化时触发。
// ... existing code ...
TextField {
id: changeInput
onTextChanged: {
console.log("输入内容已变为: " + text)
}
}
// ... existing code ...
4.2. TextArea 常用属性
文本内容相关
text:用于设置或获取文本区域当前的文本内容。placeholderText:当文本区域为空时显示的提示文本。
// ... existing code ...
TextArea {
id: multiInput
text: "默认多行文本"
placeholderText: "请输入多行内容"
}
// ... existing code ...
滚动相关
scrollBarPolicy:控制滚动条的显示策略,常见值有Qt.ScrollBarAsNeeded(按需显示)、Qt.ScrollBarAlwaysOn(始终显示)等。
// ... existing code ...
TextArea {
id: scrollableArea
scrollBarPolicy: Qt.ScrollBarAsNeeded
width: 200
height: 100
}
// ... existing code ...
只读属性
readOnly:设置文本区域是否为只读模式,值为true或false。
// ... existing code ...
TextArea {
id: readOnlyArea
text: "这是只读文本"
readOnly: true
}
// ... existing code ...
4.3. 测试效果
5. 列表控件
- ListView:用于显示列表数据。
import QtQuick 2.12
import QtQuick.Controls 2.12
ListView {
width: 200
height: 200
model: ["Item 1", "Item 2", "Item 3"]
delegate: Text {
text: modelData
}
}
在 QML 里,常见的列表控件有 ListView、GridView 和 Repeater 等,下面为你介绍这些列表控件的常用属性。
5.1. ListView 属性
数据模型属性
model:用于指定列表的数据模型,可以是数组、ListModel等。
ListView {
// ... existing code ...
model: ["Item 1", "Item 2", "Item 3"]
// ... existing code ...
}
委托属性
delegate:定义列表项的外观和行为,通常使用Component或直接在ListView中定义。
ListView {
// ... existing code ...
delegate: Text {
text: modelData
}
// ... existing code ...
}
滚动属性
flickableDirection:指定列表的滚动方向,常见值有Flickable.VerticalFlick(垂直滚动)和Flickable.HorizontalFlick(水平滚动)。boundsBehavior:控制列表滚动到边界时的行为。
ListView {
// ... existing code ...
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
// ... existing code ...
}
5.2. GridView 属性
布局属性
cellWidth** 和 **cellHeight:指定网格中每个单元格的宽度和高度。columns:指定网格的列数。
GridView {
// ... existing code ...
cellWidth: 100
cellHeight: 100
columns: 3
// ... existing code ...
}
数据模型和委托属性
GridView 同样使用 model 和 delegate 属性,用法与 ListView 类似。
GridView {
// ... existing code ...
model: ["Item 1", "Item 2", "Item 3"]
delegate: Text {
text: modelData
}
// ... existing code ...
}
5.3. Repeater 属性
数据模型属性
model:指定要重复的数据源,可以是数组、ListModel等。
Column {
Repeater {
// ... existing code ...
model: ["Item 1", "Item 2", "Item 3"]
delegate: Text {
text: modelData
}
// ... existing code ...
}
}
5.4. 测试效果
6. 图像控件
- Image:用于显示图片。
Image {
source: "image.png"
width: 100
height: 100
}
在 QML 里,图像控件主要是 Image 组件,下面为你介绍它的常用属性:
6.1. 图像源属性
source:用于指定要显示的图像文件的路径,可以是本地文件路径、网络 URL 或者资源路径。
// ... existing code ...
Image {
source: "images/logo.png" // 本地文件路径
// source: "https://example.com/image.jpg" // 网络 URL
}
// ... existing code ...
6.2. 尺寸属性
width** 和 **height:设置图像控件的宽度和高度。fillMode:控制图像如何填充控件区域,常见值有Image.Stretch(拉伸图像)、Image.PreserveAspectFit(保持宽高比适应控件)、Image.PreserveAspectCrop(保持宽高比裁剪图像)等。
// ... existing code ...
Image {
source: "images/logo.png"
width: 200
height: 200
fillMode: Image.PreserveAspectFit
}
// ... existing code ...
6.3. 对齐属性
horizontalAlignment** 和 **verticalAlignment:控制图像在控件内的水平和垂直对齐方式。
// ... existing code ...
Image {
source: "images/logo.png"
width: 200
height: 200
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
}
// ... existing code ...
6.4. 加载状态属性
status:表示图像的加载状态,常见值有Image.Null(未加载)、Image.Ready(已加载)、Image.Loading(正在加载)、Image.Error(加载出错)。onStatusChanged:图像加载状态改变时触发的信号,可以用于处理加载成功或失败的情况。
// ... existing code ...
Image {
source: "images/logo.png"
onStatusChanged: {
if (status === Image.Ready) {
console.log("图像加载成功")
} else if (status === Image.Error) {
console.log("图像加载失败: " + errorString)
}
}
}
// ... existing code ...
6.5. 缓存属性
cache:控制是否缓存图像,值为true或false。开启缓存可以提高图像的加载速度。
// ... existing code ...
Image {
source: "images/logo.png"
cache: true
}
// ... existing code ...
6.6. 测试效果
7. 布局控件
- Row:将子项水平排列。
import QtQuick.Controls 2.12
Row {
spacing: 10
Button { text: "按钮1" }
Button { text: "按钮2" }
}
- Column:将子项垂直排列。
import QtQuick.Controls 2.12
Column {
spacing: 10
Button { text: "按钮1" }
Button { text: "按钮2" }
}
在 QML 里,布局控件用于管理子控件的位置和大小,常见的布局控件有 Row、Column、Grid 和 Flow 等。下面为你介绍这些布局控件的常用属性:
7.1. Row 布局控件属性
Row 用于将子控件水平排列。
间距属性
spacing:设置子控件之间的水平间距。
import QtQuick 2.12
import QtQuick.Controls 2.12
// ... existing code ...
Row {
spacing: 10
Button { text: "按钮 1" }
Button { text: "按钮 2" }
}
// ... existing code ...
对齐属性
horizontalAlignment:设置子控件在水平方向上的对齐方式。verticalAlignment:设置子控件在垂直方向上的对齐方式。
// ... existing code ...
Row {
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
Button { text: "按钮 1" }
Button { text: "按钮 2" }
}
// ... existing code ...
7.2. Column 布局控件属性
Column 用于将子控件垂直排列。
间距属性
spacing:设置子控件之间的垂直间距。
// ... existing code ...
Column {
spacing: 10
Button { text: "按钮 1" }
Button { text: "按钮 2" }
}
// ... existing code ...
对齐属性
horizontalAlignment:设置子控件在水平方向上的对齐方式。verticalAlignment:设置子控件在垂直方向上的对齐方式。
// ... existing code ...
Column {
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
Button { text: "按钮 1" }
Button { text: "按钮 2" }
}
// ... existing code ...
7.3. Grid 布局控件属性
Grid 用于将子控件排列成网格形式。
网格属性
columns:设置网格的列数。rows:设置网格的行数。cellWidth:设置每个网格单元格的宽度。cellHeight:设置每个网格单元格的高度。
// ... existing code ...
Grid {
columns: 2
cellWidth: 100
cellHeight: 50
Button { text: "按钮 1" }
Button { text: "按钮 2" }
Button { text: "按钮 3" }
Button { text: "按钮 4" }
}
// ... existing code ...
间距属性
spacing:设置网格单元格之间的水平和垂直间距。也可以分别使用horizontalSpacing和verticalSpacing来单独设置。
// ... existing code ...
Grid {
columns: 2
spacing: 10
Button { text: "按钮 1" }
Button { text: "按钮 2" }
Button { text: "按钮 3" }
Button { text: "按钮 4" }
}
// ... existing code ...
7.4. Flow 布局控件属性
Flow 会根据可用空间自动排列子控件,当一行或一列空间不足时,会自动换行或换列。
流向属性
flow:设置子控件的排列方向,常见值有Flow.LeftToRight(从左到右)和Flow.TopToBottom(从上到下)。
// ... existing code ...
Flow {
flow: Flow.LeftToRight
spacing: 10
Button { text: "按钮 1" }
Button { text: "按钮 2" }
Button { text: "按钮 3" }
Button { text: "按钮 4" }
}
// ... existing code ...
间距属性
spacing:设置子控件之间的水平和垂直间距。也可以分别使用horizontalSpacing和verticalSpacing来单独设置。
// ... existing code ...
Flow {
flow: Flow.LeftToRight
horizontalSpacing: 10
verticalSpacing: 10
Button { text: "按钮 1" }
Button { text: "按钮 2" }
Button { text: "按钮 3" }
Button { text: "按钮 4" }
}
// ... existing code ...
7.5. 测试效果
三、最后
这个是最终的qml代码:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
//窗口控件
Window {
//1、窗口尺寸属性
width: 720
height: 1440
//2、窗口标题属性
visible: true
//3、窗口背景色属性
color: "white"
//4、窗口标题属性
title: qsTr("Hello World")
//5、窗口透明度属性
opacity: 0.5
Column {
spacing: 10
Text {
id: helloText
// 1、文字内容属性
text: qsTr("Hello World")
// 2、字体属性
font.pixelSize: 30
// 3、颜色属性
color: "red"
// 4、对齐方式属性
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignRight
// 5、换行方式属性
wrapMode: Text.WordWrap
// 6、隐藏属性
visible: true
}
Button {
id: helloButton
// 1、文字内容属性
text: qsTr("Hello Button")
// 2、尺寸属性
width: 200
height: 50
// 3、状态属性
enabled: true
// 4、样式属性
background: Rectangle {
color: "blue"
border.color: "black"
border.width: 2
radius: 10
}
// 5、信号槽属性
onClicked: {
helloText.text = qsTr("Hello Button Clicked")
}
}
TextField {
id: helloTextField
// 1、文字内容属性
placeholderText: qsTr("请输入内容:")
// 2、尺寸属性
width: 200
height: 50
// 3、输入显示模式
echoMode: TextField.Normal
// 4、信号相关
onTextChanged: {
helloText.text = helloTextField.text
}
}
ListView {
id: helloListView
// 1、尺寸属性
width: 200
height: 200
// 2、模型属性
model: [
{ text: qsTr("Hello ListView") },
{ text: qsTr("Hello ListView 1") },
{ text: qsTr("Hello ListView 2") }
]
// 3、委托属性
delegate: Text {
text: modelData.text
font.pixelSize: 20
color: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
}
// 4、滚动属性
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
// 5、信号相关
onCurrentIndexChanged: {
helloText.text = helloListView.model[helloListView.currentIndex].text
}
}
Image {
id: helloImage
// 1、图片属性
// source: "qrc:/images/hello.png"
source: "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg"
// 2、尺寸属性
width: 300
height: 200
// 3、对齐方式属性
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
// 4、加载状态属性
// 5、缓存属性
cache: false
// 6、信号相关
onStatusChanged: {
helloText.text = helloImage.status
}
}
}
}
接下来,我们再实现一下常见的滚动页面、左右切换页面、按钮按下切换页面这类的页面切换功能。