10.qml-组件、Loader、Component介绍
1.组件介绍
- 一个组件通常由一个qml文件定义(单独文件定义组件), 实际也可以在qml里面通过Component对象来嵌入式定义组件 (4小节讲解).
- Component对象封装的内容默认不会显示,除非被加载后才可能显示, 并且是可以重复加载和移除的.
- Component一般用来封装比较小,且需要重用的组件.
比如我们需要4个自定义按钮,我们只需要按钮颜色不同而已,此时就可以只需要定义一个按钮组件(Component),然后我们重复加载即可.而不是不停复制和粘贴来定义4个不同颜色的椭圆按钮.
2.单独文件定义组件
一个组件通常由一个qml文件定义,那么该文件名就是该组件的名字(类似于java,类名就是文件名).并且文件名最好是大驼峰格式.
由于我们是单独文件定义一个组件,所以不需要Component对象封装,并且创建好,我们就可以像使用qml其它元素一样来使用我们定义的组件.
首先我们创建一个名为DynamicBtn的自定义按钮组件:

DynamicBtn.qml内容如下所示:
import QtQuick 2.7
import QtQuick.Controls 2.0 Button {
id: btn
property var backColor: "#7BCBEB" // 背景颜色
property var fontPixelSize: 20 // 字体大小
property var fontColor: "#FFFFFF" text: "button"
implicitWidth: 100
implicitHeight: 30
hoverEnabled: true
contentItem: Label { // 设置文本
id: btnForeground
text: parent.text
font.family: "Microsoft Yahei"
font.pixelSize: fontPixelSize
color: fontColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle { // 绘制高亮范围
id: btnBack
color: backColor
radius: 6
Rectangle {
width: btnBack.width * 0.9
height: btnBack.height * 0.4
x: btnBack.width * 0.05
y: btnBack.height * 0.05
radius: 3
color: Qt.lighter(btnBack.color, 1.19) }
}
onDownChanged: {
btnBack.color = down ? Qt.lighter(backColor, 0.9) : backColor // 设置按下的背景颜色
}
onHoveredChanged: {
btnBack.color = hovered ? Qt.lighter(backColor, 1.2) : backColor // 设置徘徊的背景颜色
}
}
然后我们在main.qml中就可以直接使用这个DynamicBtn组件了,就像使用qml内置的Window组件那样
main.qml内容如下所示:
Window{
visible: true
function onConfirmBtnClicked() {
console.log("你点击了确认按钮");
}
function onCancelBtnClicked() {
console.log("你点击了取消按钮");
}
Column {
spacing: 20
padding: 20
DynamicBtn {
id: confirmBtn
text: "确认"
backColor: "#5CA1F6"
}
DynamicBtn {
id: cancelBtn
text: "取消"
backColor: "#FB6E62"
}
Component.onCompleted: {
confirmBtn.clicked.connect(onConfirmBtnClicked)
cancelBtn.clicked.connect(onCancelBtnClicked)
}
}
}
运行效果如下所示:

3.使用Loader对象动态加载和移除
在上节中,我们是在main.qml中直接使用这个DynamicBtn组件来静态显示,如果要动态加载和移除组件的话,则需要使用Loader对象,比如需要延时时间来显示对象之类的,都可以用Loader来实现.
Loader对象的属性如下所示:
- active : bool,默认为true,表示Loader是激活的,如果设置为false,那么加载的视图项将会被释放,但是不会影响source或 sourceComponent里的内容.
- asynchronous : bool,此属性保存组件是否将异步实例化,默认为false,在多个帧中创建组件声明的对象时,使用异步加载就可以降低动画中出现故障的可能性
- item : object,此属性保存当前加载的顶级对象。
- progress : real,此属性保存从网络加载QML数据的进度,从0.0(未加载)到1.0(完成)。大多数QML文件都很小,因此该值将迅速从0更改为1。
- source : url,此属性保存要实例化的QML组件的URL。要卸载当前加载的对象,请将此属性设置为空字符串,将source设置为新URL也将导致卸载由先前URL创建的项。
- sourceComponent : Component,此属性保存要实例化的Component,要卸载当前加载的对象,请将此属性设置为undefined
- status : enumeration,保存当前加载的状态,分别有
- Loader.Null - the loader is inactive or no QML source has been set
- Loader.Ready - the QML source has been loaded
- Loader.Loading - the QML source is currently being loaded
- Loader.Error - an error occurred while loading the QML source
Loader的信号如下所示:
- loaded() : 当status属性变为Loader.Ready成功加载后,会发出此信号。
我们还是以DynamicBtn组件为例,示例如下所示:
Window{
visible: true
function onLoad() {
loader1.source = "qrc:/DynamicBtn.qml"
loader2.source = "qrc:/DynamicBtn.qml"
}
function onRemove() {
loader1.source = ""
loader2.source = ""
}
function onConfirmBtnClicked() {
console.log("你点击了确认按钮");
btnText.text = "你点击了确认按钮"
}
function onCancelBtnClicked() {
console.log("你点击了取消按钮");
btnText.text = "你点击了取消按钮"
}
Row {
id: row
spacing: 20
padding: 20
Button {
id: load
text: "加载"
onClicked: onLoad();
}
Button {
id: remove
text: "移除"
onClicked: onRemove();
}
}
Column {
anchors.top: row.bottom
spacing: 20
padding: 20
Loader {
id: loader1
onLoaded: {
item.text = "确认"
item.backColor = "#5CA1F6"
item.clicked.connect(onConfirmBtnClicked)
}
}
Loader {
id: loader2
onLoaded: {
item.text = "取消"
item.backColor = "#FB6E62"
item.clicked.connect(onCancelBtnClicked)
}
}
Text {
id: btnText
text: "等待按钮点击"
}
}
}
界面运行起来如下所示:

点击加载按钮后如下所示:

点击移除后,那么确认和取消按钮将会消失
4. 使用Component嵌入式定义组件
如果我们不想让自定义的按钮组件单独存在一个独立文件中,而是和main.qml一起的话,则需要用Component对象来封装它,修饰该对象是个组件对象.
并且Component只能包含一个顶层item,在这个item之外除了定义id外,不能定义其它任何属性.
然后我们在Loader的sourceComponent属性填入我们要加载的Component的id,即可加载显示.
Qt帮助示例如下所示:
import QtQuick 2.0
Item {
width: 100; height: 100
Component {
id: redSquare // Component里面只有一个id和一个顶层item,这里的顶层item是一个Rectangle矩形
Rectangle {
color: "red"
width: 10
height: 10
}
}
Loader { sourceComponent: redSquare } // 加载一个矩形
Loader { sourceComponent: redSquare; x: 20 } // 在x为20的位置处再次加载一个矩形
}
我们还是以DynamicBtn组件为例,来实现一个Component,示例如下所示:
import QtQuick 2.14
import QtQuick.Window 2.0
import QtQuick.Controls 2.0 Window{
visible: true function onLoad() {
loader1.sourceComponent = dynamicBtn
loader2.sourceComponent = dynamicBtn
}
function onRemove() {
loader1.source = undefined
loader2.source = undefined
}
function onConfirmBtnClicked() {
console.log("你点击了确认按钮");
btnText.text = "你点击了确认按钮"
}
function onCancelBtnClicked() {
console.log("你点击了取消按钮");
btnText.text = "你点击了取消按钮"
} Row {
id: row
spacing: 20
padding: 20
Button {
id: load
text: "加载"
onClicked: onLoad();
}
Button {
id: remove
text: "移除"
onClicked: onRemove();
} } Column {
anchors.top: row.bottom
spacing: 20
padding: 20
Loader {
id: loader1
onLoaded: {
item.text = "确认"
item.backColor = "#5CA1F6"
item.clicked.connect(onConfirmBtnClicked)
} }
Loader {
id: loader2
onLoaded: {
item.text = "取消"
item.backColor = "#FB6E62"
item.clicked.connect(onCancelBtnClicked)
}
} Text {
id: btnText
text: "等待按钮点击" }
} Component {
id: dynamicBtn
Button {
property var backColor: "#7BCBEB" // 背景颜色
text: "button"
implicitWidth: 100
implicitHeight: 32
hoverEnabled: true
contentItem: Label { // 设置文本
id: btnForeground
text: parent.text
font.family: "Microsoft Yahei"
font.pixelSize: 20
color: "#FFFFFF"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
id: btnBack
color: backColor
radius: height / 4 Rectangle {
width: btnBack.width * 0.9
height: btnBack.height * 0.4
x: btnBack.width * 0.05
y: btnBack.height * 0.05
radius: width / 2
color: Qt.lighter(btnBack.color, 1.09) }
}
onDownChanged: {
btnBack.color = down ? Qt.lighter(backColor, 0.9) : backColor // 设置按下的背景颜色
}
onHoveredChanged: {
btnBack.color = hovered ? Qt.lighter(backColor, 1.1) : backColor // 设置徘徊的背景颜色
}
}
}
}
未完,下章学习组件其它动态创建方式:11.qml-通过方法来加载组件、字符串方式加载组件
10.qml-组件、Loader、Component介绍的更多相关文章
- QML之使用Loader加载QML组件
呵呵,今晚是边看<裸婚时代>边敲代码,那电影看得...!钱真他妈不是个东西. 盼望Meego火起来. QML的Loader元素经常备用来动态加载QML组件.可以使用source属性或者so ...
- Qt 学习之路 2(79):QML 组件
前面我们简单介绍了几种 QML 的基本元素.QML 可以由这些基本元素组合成一个复杂的元素,方便以后我们的重用.这种组合元素就被称为组件.组件就是一种可重用的元素.QML 提供了很多方法来创建组件.不 ...
- Qt 学习之路:QML 组件
前面我们简单介绍了几种 QML 的基本元素.QML 可以由这些基本元素组合成一个复杂的元素,方便以后我们的重用.这种组合元素就被称为组件.组件就是一种可重用的元素.QML 提供了很多方法来创建组件.不 ...
- React-Native之轮播组件looped-carousel的介绍与使用
React-Native之轮播组件looped-carousel的介绍与使用 一,关于react-native轮播组件的介绍与对比 1,react-native-swiper在动态使用网页图片,多张图 ...
- C# BackgroundWorker组件学习入门介绍
C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...
- hibernate 组件(Component)映射
1.类Teacher public class Teacher { private int id; private String name; private String sex; private A ...
- qml: 组件复用
在编写组件时,使用下面两种方法可以实现组件的复用: import QtQuick 2.0 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 a ...
- 「小程序JAVA实战」小程序视频组件与api介绍(51)
转自:https://idig8.com/2018/09/22/xiaochengxujavashizhanxiaochengxushipinzujianyuapijieshao50/ 这次说下,小程 ...
- 日志组件Log2Net的介绍和使用(附源码开源地址)
Log2Net是一个用于收集日志到数据库或文件的组件,支持.NET和.NetCore平台. 此组件自动收集系统的运行日志(服务器运行情况.在线人数等).异常日志.程序员还可以添加自定义日志. 该组件支 ...
随机推荐
- SHA算法摘要处理
byte[] input="sha".getBytes();//待做消息摘要算法的原始信息,可以是任意字符串 MessageDigest sha=MessageDigest.get ...
- 安装JDK步骤,配置环境变量
DK是Java语言的软件开发工具包,主要用于移动设备.嵌入式设备上的java应用程序.JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具.所以今天教一 ...
- 常用开发库 - MapStruct工具库详解
常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...
- 2017-2018 ACM-ICPC Northern Eurasia(A.Archery Tournament)
题目链接:https://vjudge.net/problem/Gym-101630A 题意: n个事件,t=1 代表增加一个圆心为(x,y),半径为 abs(y)的靶子,t=2,代表射击的坐标为(x ...
- Android Studio 待看博文
•前言 学习过程中找到的一些好的博文,有些可能当时就看完了并解决了我的问题,有些可能需要好几天的事件才能消化. 特此记录,方便查阅. •CSDN 给新人的一些基础常识 TextView的文字长度测量及 ...
- Topshelf一个用于使用.NET构建Windows服务框架
1 Topshelf是什么? Topshelf是用于托管使用.NET框架编写的Windows服务的框架.服务的创建得到简化,从而使开发人员可以创建一个简单的控制台应用程序,可以使用Topshelf将其 ...
- 前端 | 使用 ECharts 绘制关系图
0 需求 做的项目需要画一个关系图,主要需求如下: 需要展示6种对象之间的关系:数据机构 数据 合约 模型 计算机构 应用 支持突出显示6种对象中的某一种的所有对象 支持Top x子图功能.top x ...
- 带你全面认识CMMI V2.0(五)——改进
改进(Improving)涉及开发.管理和改进过程及其相关资产,其主要重点是提高组织绩效.保持习惯和持久性可确保过程在整个组织中是持久.习惯性地执行和维持,并有助于有效地实现业务绩效目标.治理(GOV ...
- RPC理论介绍
目录 RPC概述 RPC是什么 和本地调用有什么区别 RPC模式 RPC的三个过程 为什么要使用RPC RPC和其他协议的区别 RPC使用场景 RPC的流程 RPC核心概念术语 RPC协议 RPC框架 ...
- 如何在 NET 程序万种死法中有效的生成 Dump (下)
一:背景 上一篇我们聊到了如何通过 procdump 抓取 cpu爆高 和 内存暴涨 两种情况,这一篇再聊聊如何去抓程序 挂死 和 意外退出. 二:程序挂死 1. 定义 程序挂死 简单的说就是程序没有 ...