博客24## 一、Components(组件)

Component 是由 Qt 框架或开发者封装好的、只暴露了必要接口的 QML 类型,可以重复利用。一个 QML 组件就像一个黑盒子,它通过属性、信号、函数和外部世界交互。

一个 Component 即可以定义在独立的 qml 文件中,也可以嵌入到其它的 qml 文档中来定义。通常我们可以根据这个原则来选择将一个 Component 定义在哪里:如果一个 Component 比较小且只在某个 qml 文档中使用或者一个 Component 从逻辑上看从属于某个 qml 文档,那就可以采用嵌入的方式来定义该 Component 。你也可以与 C++ 的嵌套类对比来理解。

嵌入式定义组件

示例 QML 代码如下:

import QtQuick 2.0
import QtQuick.Controls 1.1 Rectangle {
width: 320;
height: 240;
color: "#C0C0C0"; Text {
id: coloredText;
anchors.horizontalCenter: parent.horizontalCenter;
anchors.top: parent.top;
anchors.topMargin: 4;
text: "Hello World!";
font.pixelSize: 32;
} Component {
id: colorComponent;
Rectangle {
id: colorPicker;
width: 50;
height: 30;
signal colorPicked(color clr);
MouseArea {
anchors.fill: parent
onPressed: colorPicker.colorPicked(colorPicker.color);
}
}
} Loader{
id: redLoader;
anchors.left: parent.left;
anchors.leftMargin: 4;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 4;
sourceComponent: colorComponent;
onLoaded:{
item.color = "red";
}
} Loader{
id: blueLoader;
anchors.left: redLoader.right;
anchors.leftMargin: 4;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 4;
sourceComponent: colorComponent;
onLoaded:{
item.color = "blue";
}
} Connections {
target: redLoader.item;
onColorPicked:{
coloredText.color = clr;
}
} Connections {
target: blueLoader.item;
onColorPicked:{
coloredText.color = clr;
}
}
}

如你所见,要在一个 QML 文档中嵌入 Component 的定义,需要使用 Component 对象。

定义一个 Component 与定义一个 QML 文档类似, Component 只能包含一个顶层 item ,而且在这个 item 之外不能定义任何数据,除了 id 。比如上面的代码中,顶层 item 是 Rectangle 对象,在 Rectangle 之外我定义了 id 属性,其值为 colorComponent 。而顶层 item 之内,则可以包含更多的子元素来协同工作,最终形成一个具有特定功能的组件。

Component 通常用来给一个 view 提供图形化组件,比如ListView::delegate属性就需要一个 Component 来指定如何显示列表的每一个项,又比如ButtonStyle::background属性也需要一个 Component 来指定如何绘制 Button 的背景。

Component 不是 Item 的派生类,而是从 QQmlComponent 继承而来,虽然它通过自己的顶层 item 为其它的 view 提供可视化组件,但它本身是不可见元素。你可以这么理解:你定义的组件是一个新的类型,它必须被实例化以后才可能显示。而要实例化一个嵌入在 qml 文档中定义的组件,则可以通过 Loader。后面我们详细讲述 Loader ,这里先按下不表。

二、使用 Loader

2.1 Loader 的详细介绍

Loader 用来动态加载 QML 组件。Loader 可以使用其 source 属性加载一个 qml 文档,也可以通过其 sourceComponent 属性加载一个 Component 对象。当你需要延迟一些对象直到真正需要才创建它们时, Loader 非常有用。

当 Loader 的 source 或 sourceComponent 属性发生变化时,它之前加载的 Component 会自动销毁,新对象会被加载。将 source 设置为一个空字符串或将 sourceComponent 设置为 undefined ,将会销毁当前加载的对象,相关的资源也会被释放,而 Loader 对象则变成一个空对象。

Loader 的 item 属性指向它加载的组件的顶层 item ,比如 Loader 加载了我们的颜色选择组件,其 item 属性就指向颜色选择组件的 Rectangle 对象。对于 Loader 加载的 item ,它暴露出来的接口,如属性、信号等,都可以通过 Loader 的 item 属性来访问。所以我们才可以这么使用:

Loader{
id: redLoader;
anchors.left: parent.left;
anchors.leftMargin: 4;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 4;
sourceComponent: colorComponent;
onLoaded:{
item.color = "red";
}
}

上面的代码在 Loader 对象使用 sourceComponent 属性来加载 id 为 colorComponent 的组件对象,然后在 onLoaded 信号处理器中使用 item 属性来设置颜色选择组件的颜色。对于信号的访问,我们则可以使用 Connections 对象,如下面的 qml 代码所示:

Connections {
target: redLoader.item;
onColorPicked:{
coloredText.color = clr;
}
}

我们创建的 Connections 对象,其 target 指向 redLoader.item ,即指向颜色选择组件的顶层 item — Rectangle ,所以可以直接响应它的 colorPicked 信号。

虽然 Loader 本身是 Item 的派生类,但没有加载 Component 的 Loader 对象是不可见的,没什么实际的意义。而一旦你加载了一个 Component , Loader 的大小、位置等属性却可以影响它所加载的 Component 。

如果你没有显式指定 Loader 的大小,那么 Loader 会将自己的尺寸调整为与它加载的可见 item 的尺寸一致;如果 Loader 的大小通过 width 、 height 或 锚布局显式设置了,那么它加载的可见 item 的尺寸会被调整以便适应 Loader 的大小。不管是哪种情况, Loader 和它所加载的 item 具有相同的尺寸,这确保你使用锚来布局 Loader 就等同于布局它加载的 item 。

2.2 从文件加载组件

之前介绍 Loader 时,我们以嵌入式定义的 Component 为例子说明 Loader 的各种特性和用法,现在我们来看如何从文件加载组件。

对于定义在一个独立文件中的 Component ,同样可以使用 Loader 来加载,只要指定 Loader 的 source 属性即可。现在再来修改下我们的例子,使用 Loader 来加载 ColorPicker 组件。

示例代码如下:

import QtQuick 2.0
import QtQuick.Controls 1.1 Rectangle {
width: 320;
height: 240;
color: "#EEEEEE"; Text {
id: coloredText;
anchors.horizontalCenter: parent.horizontalCenter;
anchors.top: parent.top;
anchors.topMargin: 4;
text: "Hello World!";
font.pixelSize: 32;
} Loader{
id: redLoader;
width: 80;
height: 60;
focus: true;
anchors.left: parent.left;
anchors.leftMargin: 4;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 4;
source: "ColorPicker.qml";
KeyNavigation.right: blueLoader;
KeyNavigation.tab: blueLoader; onLoaded:{
item.color = "red";
item.focus = true;
} onFocusChanged:{
item.focus = focus;
}
} Loader{
id: blueLoader;
focus: true;
anchors.left: redLoader.right;
anchors.leftMargin: 4;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 4;
source: "ColorPicker.qml";
KeyNavigation.left: redLoader;
KeyNavigation.tab: redLoader; onLoaded:{
item.color = "blue";
} onFocusChanged:{
item.focus = focus;
}
} Connections {
target: redLoader.item;
onColorPicked:{
coloredText.color = clr;
if(!redLoader.focus){
redLoader.focus = true;
blueLoader.focus = false;
}
}
} Connections {
target: blueLoader.item;
onColorPicked:{
coloredText.color = clr;
if(!blueLoader.focus){
blueLoader.focus = true;
redLoader.focus = false;
}
}
}
}

代码有几处改动:

一处是将 sourceComponent 修改为 source ,其值为 "ColorPicker.qml" 。

一处是两个 Connections 对象,在 onColorPicked 信号处理器中,设置了 Loader 的焦点属性,因为只有 Loader 有焦点,它加载的 item 才会有焦点,如果你鼠标点击某个颜色选择组件而加载它的 Loader 没有焦点,那么虽然颜色可以改变,但是焦点框出不来。

使用 Loader 加载定义在 qml 文档中的组件,比直接使用组件名构造对象要繁琐得多,但如果你的应用会根据特定的情景来决定某些界面元素是否显示,这种方式也许可以满足你。

参考:

《Qt Quick核心编程》第7章

Qt Quick 组件与对象动态创建详解

Qt Quick 组件与动态对象的更多相关文章

  1. Qt Quick 组件和动态创建的对象具体的解释

    在<Qt Quick 事件处理之信号与槽>一文中介绍自己定义信号时,举了一个简单的样例.定义了一个颜色选择组件,当用户在组建内点击鼠标时,该组件会发出一个携带颜色值的信号,当时我使用 Co ...

  2. Qt Quick 布局演示

    于 Qt Widgets 于,我们经常使用许多布局管理器来管理界面 widgets . 于 Qt Quick 实际上,有两个相关的管理和布局库,所谓集 Item Positioner ,所谓集 Ite ...

  3. Qt Quick实现的涂鸦程序

    之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...

  4. Qt Quick实现的疯狂算数游戏

    使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QM ...

  5. Qt Quick 事件处理之信号与槽

    前面两篇文章<QML 语言基础>和<Qt Quick 简单教程>中我们介绍了 QML 语言的基本的语法和 Qt Quick 的常见元素,亲们,通过这两篇文章,您应该已经能够完毕 ...

  6. Qt Quick之StackView具体解释(1)

    Qt Quick中有个StackView.我在<Qt Quick核心编程>一书中没有讲到.近期有人问起,趁机学习了一下,把它的基本使用方法记录下来. 我准备分两次来讲.第一次讲主要的使用方 ...

  7. Qt Quick 图像处理实例之美图秀秀(附源代码下载)

    在<Qt Quick 之 QML 与 C++ 混合编程具体解释>一文中我们解说了 QML 与 C++ 混合编程的方方面面的内容,这次我们通过一个图像处理应用.再来看一下 QML 与 C++ ...

  8. Qt Quick综合实例之文件查看器

    假设你基于Qt SDK 5.3.1来创建一个Qt Quick App项目,项目模板为你准备的main.qml文档的根元素是ApplicationWindow或Window.这次我们就以Applicat ...

  9. Qt Quick 之 QML 与 C++ 混合编程具体解释

    Qt Quick 技术的引入.使得你能够高速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的.也有非常多局限性,原来 Qt 的一些技术,比方低阶的网络编程如 QTcpSocke ...

随机推荐

  1. 【05】Nginx:TCP / 正向 / 反向代理 / 负载均衡

    写在前面的话 在我们日常的工作中,不可能所有的服务都是简单的 HTML 静态网页,nginx 作为轻量级的 WEB 服务器,其实我们将它用于更多的地方还是作为我们网站的入口.不管你是后端接口,还是前端 ...

  2. windows 安装gitea

    gitea 地址https://github.com/go-gitea/gitea windows 安装 

  3. .net core 3.0中的Json API

    在.net core 3.0中,内置了一套新的json api,主要用于去除asp.net core对json.net的依赖,同时也提供了更好的性能(直接处理 UTF-8,而无需转码到 UTF-16) ...

  4. 今日头条3面,被泄露的Java最新面试题

    一.面试第 1 轮 1. linux 网络模型 2. b+树 3. 阻塞队列 4. redis 和 MongoDB 的区别.几个概念对比,还有底层实现. 5. 算法题: merge k sorted ...

  5. tomcat的基本应用

    1.JVM基本介绍 JAVA编译型 ---> 编译 C 编译型---> linux --->编译一次 windows --->编译一次 macos ubuntu 跨平台 移值型 ...

  6. IntelliJ IDEA 中使用 Lambok (注解无效问题的解决)

    一,概述 Lambok可以说一个能很大提高开发效率的插件,只要在使用注解的方式就能实现很多常用的功能.如常用的@Data能在编译阶段自动生成toString方法,getter方法setter方法等. ...

  7. 搞NDK开发

    1.哪些场景下要用到NDK开发? 跨平台的库,如FFmpeg, skip,weex, 加固,防逆向 签名校验 图片压缩 音视频解码 OpenGL ES 高级特效 热修复 andfix 人脸识别 fac ...

  8. https抓包 Fiddler

    打开Fiddler https抓包 安装证书 查看证书 打开Windows程序certmgr.msc 查找Fiddler证书 查看Fiddler证书是否安装成功 测试连接 使用Google Chrom ...

  9. VMware基本用法

    ###VMware tools 介绍 只有在VMware虚拟机中安装好了VMware Tools,才能实现主机与虚拟机之间的文件共享,同时可支持自由拖拽的功能,鼠标也可在虚拟机与主机之前自由移动(不用 ...

  10. 章节十四、9-Actions类鼠标悬停、滚动条、拖拽页面上的元素

    一.鼠标悬停 1.在web网站中,有一些页面元素只需要我们将鼠标指针放在上面就会出现被隐藏的下拉框或者其它元素,在自动化的过程中我们使用Actions类对鼠标进行悬停操作. 2.案例演示 packag ...