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,保存当前加载的状态,分别有
  1. Loader.Null - the loader is inactive or no QML source has been set
  2. Loader.Ready - the QML source has been loaded
  3. Loader.Loading - the QML source is currently being loaded
  4. 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介绍的更多相关文章

  1. QML之使用Loader加载QML组件

    呵呵,今晚是边看<裸婚时代>边敲代码,那电影看得...!钱真他妈不是个东西. 盼望Meego火起来. QML的Loader元素经常备用来动态加载QML组件.可以使用source属性或者so ...

  2. Qt 学习之路 2(79):QML 组件

    前面我们简单介绍了几种 QML 的基本元素.QML 可以由这些基本元素组合成一个复杂的元素,方便以后我们的重用.这种组合元素就被称为组件.组件就是一种可重用的元素.QML 提供了很多方法来创建组件.不 ...

  3. Qt 学习之路:QML 组件

    前面我们简单介绍了几种 QML 的基本元素.QML 可以由这些基本元素组合成一个复杂的元素,方便以后我们的重用.这种组合元素就被称为组件.组件就是一种可重用的元素.QML 提供了很多方法来创建组件.不 ...

  4. React-Native之轮播组件looped-carousel的介绍与使用

    React-Native之轮播组件looped-carousel的介绍与使用 一,关于react-native轮播组件的介绍与对比 1,react-native-swiper在动态使用网页图片,多张图 ...

  5. C# BackgroundWorker组件学习入门介绍

    C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...

  6. hibernate 组件(Component)映射

    1.类Teacher public class Teacher { private int id; private String name; private String sex; private A ...

  7. qml: 组件复用

    在编写组件时,使用下面两种方法可以实现组件的复用: import QtQuick 2.0 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 a ...

  8. 「小程序JAVA实战」小程序视频组件与api介绍(51)

    转自:https://idig8.com/2018/09/22/xiaochengxujavashizhanxiaochengxushipinzujianyuapijieshao50/ 这次说下,小程 ...

  9. 日志组件Log2Net的介绍和使用(附源码开源地址)

    Log2Net是一个用于收集日志到数据库或文件的组件,支持.NET和.NetCore平台. 此组件自动收集系统的运行日志(服务器运行情况.在线人数等).异常日志.程序员还可以添加自定义日志. 该组件支 ...

随机推荐

  1. CodeMonkey少儿编程第7章 函数

    目标 了解函数是什么 掌握如何定义一个函数 函数是什么 本章我们学习一个新的概念----函数. 你可以简单的将函数看作为一个黑匣子,给它输入参数后,它将会按照一定的规则,执行相应的指令或输出数据. 让 ...

  2. JavaWeb开发中的分层思想(一)

    JavaWeb开发分层思想(一) 一.认识DAO.Service.Controller层 DAO(Data Access Object) 1.直接看英文意思就是"数据访问对象",也 ...

  3. 画直线的算法之DDA算法+代码实现(法一)

    DDA(数值微分法)基于直线微分方程生成直线. 点xi,yi满足直线方程yi=kxi+b, 若xi增加一个单位,则下一步点的位置(xi + 1,yi+1)满足yi+1=k(xi + 1)+ b. 即y ...

  4. 11、Spring教程之声明式事务

    1.回顾事务 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎! 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性. 事务就是把一系列的动作当成一个独立的工作单元,这 ...

  5. 12、MyBatis教程之缓存

    13.缓存 简介 1.什么是缓存 [ Cache ]? 存在内存中的临时数据. 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高 ...

  6. MySQL的安装及使用

    安装MySQL 这里建议大家使用压缩版,安装快,方便.不复杂. 1.MySQL软件下载 mysql5.7 64位下载地址: https://dev.mysql.com/get/Downloads/My ...

  7. python那些需要知道的事儿——内存泄漏

    啥,内存也会泄露?漏了咋补?我的内存会不会越漏越小?咋一听到内存泄漏,本喵的脑子蹦出无数想法,所以到底啥是内存泄漏! 一.垃圾回收机制(GC)机制 在理解内存泄漏之前,需要补充一个知识,即GC机制(也 ...

  8. 第27 章 : Kubernetes 安全之访问控制

    Kubernetes 安全之访问控制 本文将主要分享以下三方面的内容: Kubernetes API 请求访问控制 Kubernetes 认证 Kubernetes RBAC Security Con ...

  9. 全网最详细的新手入门Mysql命令和基础,小白必看!

    MySQL简介 什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅是 ...

  10. 深度学习---1cycle策略:实践中的学习率设定应该是先增再降

    深度学习---1cycle策略:实践中的学习率设定应该是先增再降 本文转载自机器之心Pro,以作为该段时间的学习记录 深度模型中的学习率及其相关参数是最重要也是最难控制的超参数,本文将介绍 Lesli ...