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. validator库参数校验

    目录 validator库参数校验若干实用技巧 基本示例 翻译校验错误提示信息 自定义错误提示信息的字段名 自定义结构体校验方法 自定义字段校验方法 自定义翻译方法 validator库参数校验若干实 ...

  2. GO基础知识分享

    目录 GO基础知识分享 go语言的基本事项 关键字 字符串的拼接和变量的定义方式 空白符 const常量 iota的用法 运算符 Go 没有三目运算符,不能适用?: 语言条件语句 for循环的方式 函 ...

  3. 以绝对优势立足:从CDN和云存储来聊聊云生态的崛起

    以绝对优势立足:从CDN和云存储来聊聊云生态的崛起 前面几期文章我们介绍了混合云模式,以及面向应用层的云架构解决方案的Spring Cloud.接下来,我们就以蘑菇街的两个具体案例,来分享一下基于混合 ...

  4. 使用ffmpeg 操作音频文件前后部分静音移除.

    指令特别简单, 但是却琢磨了一下午. 总结看文档时要细心, 主要ffmpeg的版本要 8.2.1 以上 ffmpeg -i in.mp3 -af silenceremove=start_periods ...

  5. day-08-文件管理

    文件的操作的初识 利用python代码写一个很low的软件,去操作文件. 文件路径:path 打开方式:读,写,追加,读写,写读...... 编码方式:utf-8,gbk ,gb2312...... ...

  6. java正则匹配${xxx} 排除单引号双引号内的内容,前提引号必须成对出现

    public static void main(String[] a) { String wpp = "select 1, ${mark} '``this is, `/message22` ...

  7. vue+quasar+electron+springboot+mysql撸一个TODO LIST 看板

    先看效果 写本项目的目的有几点: 学习下vue+electron桌面开发 学习下java和spring开发(本人一直使用PHP) 一直缺少一款能适合自己的TODO LIST软件,能有桌面端的 可直接打 ...

  8. M3D - 一个想突破又还有很多包袱的新生三维数据格式杂谈

    目录 1 门派 2 几个术语简析 3 结构简析 3.1 空间剖分方式 3.2 空间范围表示方式 4 M3DDataInfo.mcj 类定义 5 NodeInfo.json 类定义 6 *.m3d 文件 ...

  9. Leedcode算法专题训练(分治法)

    归并排序就是一个用分治法的经典例子,这里我用它来举例描述一下上面的步骤: 1.归并排序首先把原问题拆分成2个规模更小的子问题. 2.递归地求解子问题,当子问题规模足够小时,可以一下子解决它.在这个例子 ...

  10. 10. linux 系统启动流程

    POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel-->initrd-->(ROOTFS)/sbin/in ...