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. C#无边框窗体拖动代码

    1.重写 protected override void WndProc(ref Message m) { if (m.Msg == 163 && this.ClientRectang ...

  2. 小白的第一次sql实战

    去年发的有一篇sql注入忘记粘贴过来了,今天想起了就fuzz过来一下 有id尝试sql注入 找这种sql注入的站用sql检索就行了,但是最好挂代理用谷歌搜索,百度的话搜sql注入的很多被别人打过了,导 ...

  3. Java例题_30 在已经排好序的数组中插入值

    1 /*30 [程序 30 插入数字] 2 题目:有一个已经排好序的数组.现输入一个数,要求按原来的规律将它插入数组中. 3 程序分析:首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插 ...

  4. NetCore的缓存使用详例

    关于我 作者博客|文章首发 缓存基础知识 缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能和可伸缩性. 缓存最适用于不经常更改的 数据,生成 成本很高. 通过缓存,可以比从数据源返回的数据的 ...

  5. Java学习之随机数的用法

    •前言 随机数的产生在一些代码中很常用,也是我们必须要掌握的. 而 Java 中产生随机数的方法主要有三种: new Random() Math.random() currentTimeMillis( ...

  6. 第1课:Linux操作系统基础【DevOps基础培训】

    第1课:Linux操作系统基础 --DevOps基础培训 1. 云主机.公网IP 1.1 公网ip和私网ip 只有公网ip是能够连接互联网的,私网IP 一般只用作局域网 我们能够上网靠的是isp组织分 ...

  7. shell的配置文件

    1. bash shell 的配置文件 bash shell的配置文件很多,可以分成下面类别 1.1 按生效范围划分两类 全局配置:针对所有用户皆有效 /etc/profile /etc/profil ...

  8. [DP]城市交通

    城市交通 Time Limit:1000MS--Memory Limit:65536K 题目描述 有n个城市,编号1~n,有些城市之间有路相连,有些则没有,有路则当然有一个距离.现在规定只能从编号小的 ...

  9. (原创)高DPI适配经验系列:(二)按DPI范围适配

    一.前言 一个软件,往往会用到位图资源,比如图标.图片.水晶按钮等. 在使用了位图资源后,就不能对任意DPI都进行适配,因为这样适配的代价太大了. 像Win10的缩放比例可以由100%-500%,如果 ...

  10. Spring Cloud Alibaba(2)---Nacos概述

    Spring Cloud Alibaba(2)---nacos概述 上一篇博客讲了有关 SpringCloudAlibaba的概述,这篇开始讲SpringCloudAlibaba组件之一---Naco ...