QML Loader:延迟加载与动态切换
目录
- 引言
- 相关阅读
- 工程结构
- LoaderDelay.qml - 延迟加载实现
- 完整代码
- HeavyComponent.qml
- 代码解析
- 运行效果
- LoaderSwitch.qml - 动态切换组件
- 完整代码
- 代码解析
- 运行效果
- Main.qml - 主界面实现
- 完整代码
- 主界面结构
- 代码解析
- 总结
- 下载链接
引言
QML的Loader组件提供了一种强大的机制,使开发者能够动态加载和卸载QML组件,这对于优化内存使用和提升应用性能至关重要。本文将通过两个实用示例:延迟加载和组件切换,深入探讨Loader组件的应用场景和技术细节。
相关阅读
- QML Loader组件:动态加载与控件创建
- QML Loader:加载组件与状态监控
工程结构
LoaderDelay.qml - 延迟加载实现
在某些场景下,我们需要加载资源密集型组件,但又不希望在应用启动时立即加载,以避免启动延迟。通过Loader结合Timer,可以实现按需延迟加载。
完整代码
import QtQuick
import QtQuick.ControlsRectangle {color: "lightgray"Column {anchors.centerIn: parentspacing: 10Button {text: "延迟加载"onClicked: {busyIndicator.running = truedelayTimer.start()}anchors.horizontalCenter: parent.horizontalCenter}BusyIndicator {id: busyIndicatorrunning: falseanchors.horizontalCenter: parent.horizontalCenter}Loader {id: loaderwidth: 200height: 200anchors.horizontalCenter: parent.horizontalCenter}}Timer {id: delayTimerinterval: 2000 // 延迟2秒加载onTriggered: {loader.source = "component/HeavyComponent.qml"busyIndicator.running = false}}
}
HeavyComponent.qml
import QtQuick
import QtQuick.ControlsRectangle {width: 200height: 200color: "#666"Column {anchors.centerIn: parentspacing: 15Text {text: "耗时组件已加载完成"font.pixelSize: 16color: "#333"anchors.horizontalCenter: parent.horizontalCenter}Text {text: "加载用时:2秒"font.pixelSize: 14color: "#333"anchors.horizontalCenter: parent.horizontalCenter}// 旋转的方块Rectangle {width: 50height: 50color: "white"anchors.horizontalCenter: parent.horizontalCenterRotationAnimation on rotation {from: 0to: 360duration: 3000loops: Animation.Infinite}}}
}
代码解析
延迟加载机制:
- LoaderDelay.qml中包含一个空的Loader组件,初始状态下不加载任何内容
- 点击"延迟加载"按钮后,显示BusyIndicator并启动Timer
- Timer触发后(2秒延迟),Loader加载HeavyComponent.qml并隐藏BusyIndicator
用户交互流程:
- 用户点击按钮 → 显示加载指示器 → 延迟2秒 → 加载重型组件 → 隐藏加载指示器
HeavyComponent组件:
- 模拟一个资源密集型组件,包含文本和动画效果
- 在实际应用中,这可能是包含复杂图形、大量数据处理或网络请求的组件
运行效果

LoaderSwitch.qml - 动态切换组件
使用Loader动态切换不同组件是一种常见需求,特别是在需要根据用户操作或系统状态切换界面时。
完整代码
import QtQuick
import QtQuick.ControlsRectangle {color: "lightgray"Column {anchors.centerIn: parentspacing: 20Switch {id: controlSwitchtext: "切换组件"anchors.horizontalCenter: parent.horizontalCenter}Loader {width: 200height: 100anchors.horizontalCenter: parent.horizontalCentersourceComponent: controlSwitch.checked ? component1 : component2}}Component {id: component1Rectangle {width: 200height: 100color: "red"Text {anchors.centerIn: parenttext: "组件 1"color: "white"}}}Component {id: component2Rectangle {width: 200height: 100color: "blue"Text {anchors.centerIn: parenttext: "组件 2"color: "white"}}}
}
代码解析
组件切换机制:
- 通过Switch控件控制Loader加载的组件
- 使用三元操作符(?:)根据Switch状态动态切换sourceComponent属性
- 当Switch被选中时加载component1(红色矩形),未选中时加载component2(蓝色矩形)
内联Component定义:
- 两个组件直接在文件中定义,而非外部文件
- 这种方式适合简单组件,减少了文件数量,提高了代码可读性
绑定与自动更新:
- sourceComponent属性与Switch状态的绑定确保UI自动更新
- 无需额外编写信号处理代码
运行效果

Main.qml - 主界面实现
为了将所有示例串联起来,我们使用了Main.qml作为主界面,它采用左侧列表 + 右侧内容区的布局方式。
完整代码
import QtQuick
import QtQuick.Controls
import QtQuick.LayoutsApplicationWindow {visible: truewidth: 800height: 600title: "QML Loader 示例"RowLayout {anchors.fill: parentspacing: 10// 左侧选择栏ListView {Layout.preferredWidth: 200Layout.fillHeight: truemodel: ["文件加载","组件加载","加载状态","动态标签","创建控件","延迟加载","切换组件"]delegate: ItemDelegate {width: parent.widthtext: modelDatahighlighted: ListView.isCurrentItemonClicked: {listView.currentIndex = indexswitch(index) {case 0: mainLoader.source = "LoaderFile.qml"; breakcase 1: mainLoader.source = "LoaderComponent.qml"; breakcase 2: mainLoader.source = "LoaderStatus.qml"; breakcase 3: mainLoader.source = "LoaderDynamicTab.qml"; breakcase 4: mainLoader.source = "LoaderCreateControls.qml"; breakcase 5: mainLoader.source = "LoaderDelay.qml"; breakcase 6: mainLoader.source = "LoaderSwitch.qml"; break}}}id: listView}// 右侧内容区Loader {id: mainLoaderLayout.fillWidth: trueLayout.fillHeight: truesource: "LoaderFile.qml"}}
}
主界面结构
代码解析
布局设计:
- 使用RowLayout实现左右分栏布局
- 左侧列表固定宽度,右侧内容区自适应填充
导航机制:
- ListView结合ItemDelegate实现导航列表
- 点击列表项更新currentIndex并切换mainLoader的source
动态加载:
- 主界面本身使用Loader加载各个示例组件
- 实现了示例之间的无缝切换,避免所有组件同时加载消耗资源
总结
通过本文的两个示例,我们展示了QML Loader组件在不同场景下的应用:
延迟加载(LoaderDelay.qml):
- 按需加载复杂组件,提升应用启动性能
- 配合BusyIndicator提供良好的用户体验
- 使用Timer实现延迟加载机制
动态切换(LoaderSwitch.qml):
- 基于用户输入实时切换UI组件
- 使用内联Component定义简化代码结构
- 通过绑定实现自动UI更新
Loader组件是QML中的性能优化利器,它能够:
- 减少初始加载时间和内存占用
- 实现UI组件的动态切换和按需加载
- 根据用户操作或应用状态灵活管理界面
下载链接
完整代码可在以下地址获取:GitCode - QML Loader示例

相关文章:
QML Loader:延迟加载与动态切换
目录 引言相关阅读工程结构LoaderDelay.qml - 延迟加载实现完整代码HeavyComponent.qml代码解析运行效果 LoaderSwitch.qml - 动态切换组件完整代码代码解析运行效果 Main.qml - 主界面实现完整代码主界面结构代码解析 总结下载链接 引言 QML的Loader组件提供了一种强大的机制…...
Python和MicroPython的解释器区别
Python和MicroPython的解释器不是同一个,它们在设计目标、实现方式和运行环境上都有显著的区别。以下是它们的主要区别: 1. 底层实现 Python解释器(CPython): Python的标准解释器是CPython(C语言实现的Pyt…...
Git 的进阶功能和技巧
1、分支的概念和使用 1.1、什么是分支? 分支(Branch)是在版本控制中非常重要的概念。几乎所有版本控制系统都支持某种形式的分支。在 Git 中,分支是 Git 强大功能之一,它允许我们从主开发线分离出来,在不…...
解析HiveQL的ALTER TABLE ADD/REPLACE COLUMNS语句
阅读以下ALTER TABLE的ADD/REPLACE COLUMNS语句的语法,用C#编写解析函数,一个一个字符解析,所有关键字不区分大小写,一个或多个空格、Tab和换行的组合都可以是关键词之间的分隔,表名和字段名可能包含空格和Tab,语句中可以用`包裹表名和字段名,解析以下HiveQL语句在所有可…...
Spark Core编程
一 Spark 运行架构 1 运行架构 定义 Spark 框架的核心是一个计算引擎,整体来说,它采用了标准 master-slave 的结构 如图所示 2 核心组件 Spark 框架有两个核心组件: 1)Driver 2)Spark 驱动器节点(用于执行 Spark 任务中的 main 方法&…...
在Ubuntu内网环境中为Gogs配置HTTPS访问(通过Apache反向代理使用IP地址)
一、准备工作 确保已安装Gogs并运行在HTTP模式(默认端口3000) 确认服务器内网IP地址(如192.168.1.100) 二、安装Apache和必要模块 sudo apt update sudo apt install apache2 -y sudo a2enmod ssl proxy proxy_http rewrite headers 三、创建SSL证书 1. 创建证书存储目录…...
Kafka和RocketMQ相比有什么区别?那个更好用?
Kafka和RocketMQ相比有什么区别?那个更好用? Kafka 和 RocketMQ 都是广泛使用的消息队列系统,它们有很多相似之处,但也有一些关键的区别。具体选择哪个更好用,要根据你的应用场景和需求来决定。以下是它们之间的主要区别: 1. …...
无人机装调与测试
文章目录 前言一、无人机基本常识/预备知识(一)无人机飞行原理无人机硬件组成/各组件作用1.飞控2.GPS3.接收机4.电流计5.电调6.电机7.电池8.螺旋桨9.UBEC(稳压模块) (二)飞控硬件简介(三&#x…...
JavaScript Hook JSON.stringify和JSON.parse:逆向与修改实战指南
在JavaScript逆向工程中,Hook JSON.stringify和JSON.parse方法是一种重要的技术,可以用来捕获、修改或分析JSON数据的序列化和反序列化过程。本文将结合具体案例,详细讲解如何实现这些方法的Hook操作。 一、Hook JSON.stringify和JSON.parse…...
【图书管理系统】全栈开发图书管理系统获取图书列表接口(后端:计算图书页数、查询当前页展示的书籍)
图书列表 实现服务器代码(计算图书总数量查询当前页需要展示的书籍) 后端响应时,需要响应给前端的数据 records:第 pageNum 页要展示的图书有哪些(存储到List集合中)total:计算一共有多少本书(用于告诉前…...
正则表达式补充——python
简介 本章是对前面正则表达式的补充。 一、复杂的查找替换等任务 content 张三是脑卒中病 李四,是高血脂 苏齐,是肺结核病 六六,是血血血血import re p re.compile(r...病) for one in p.findall(content):print(one) 运行结果…...
Kotlin日常使用函数记录
文章目录 前言字符串集合1.两个集合的差集2.集合转数组2.1.集合转基本数据类型数组2.2.集合转对象数组 Map1.合并Map1.1.使用 操作符1.2.使用 操作符1.3.使用 putAll 方法1.4.使用 merge 函数 前言 记录一些kotlin开发中,日常使用的函数和方式之类的,…...
Android 回答视频边播放边下载的问题
分层次的回答突出 技术深度、架构思维 和 实战优化,从基础实现到高阶优化: 一、核心技术方案(基础回答) 如何实现视频边下边播? 1. **网络请求**:使用 HTTP Range 请求(Header: Range: bytes0…...
RHCSA Linux系统 数据流和重定向 tee 命令
一.数据流和重定向 1. 数据流 (1) 标准输入(stdin,代码 0):默认从键盘获取输入,只读。 (2) 标准输出(stdout,代码 1):命令执行正确信息默认输出到屏幕,只写…...
[ctfshow web入门] web7
信息收集 题目提示:版本控制很重要,但不要部署到生产环境更重要。 那么很有可能,版本控制相关的信息被部署到环境了,比如比如version.txt记录了一些相关配件的版本,git版本管理工具中的.git文件夹未删除 信息收集就是…...
DeepSeek-V3 API:开启下一代AI应用开发的新篇章
引言 在人工智能技术日新月异的今天,大型语言模型(LLM)正以前所未有的速度改变着我们与技术互动的方式。DeepSeek-V3作为国内领先的大语言模型之一,其API的开放为开发者提供了强大的AI能力集成方案。 DeepSeek-V3 API的核心优势 1.强大的语言理解与生…...
华为数字芯片机考2025合集3已校正
1. 题目内容 下列说法正确的是()。 1. 解题步骤 1.1 选项分析 选项描述正误依据A异步 FIFO 采用格雷码是为了省功耗✗格雷码用于消除多比特信号跨时钟域的位跳变风险,与功耗无关B单比特信号打两拍可以完全避免亚稳态✗双触发器同步仅降低…...
控制 ElementUI el-table 树形表格多选框的显示层级
1、你可以通过 selectable 属性来控制哪些行可以选择(显示多选框) <el-table:data"tableData"row-key"id"default-expand-all:tree-props"{children: children, hasChildren: hasChildren}"select"handleSelect&…...
go语言应该如何学习
以下是学习Go语言的高效路径及关键技巧,结合多个优质来源整理而成,适合不同基础的学习者: 一、基础语法快速入门(1-2周) 1、环境搭建 下载安装Go SDK,配置GOPATH和GOROOT环境变量,推荐使用Go…...
NO.84十六届蓝桥杯备战|动态规划-路径类DP|矩阵的最小路径和|迷雾森林|过河卒|方格取数(C++)
路径类dp是线性dp的⼀种,它是在⼀个nm的矩阵中设置⼀个⾏⾛规则,研究从起点⾛到终点的⽅案数、最⼩路径和或者最⼤路径和等等的问题 矩阵的最小路径和_牛客题霸_牛客网 状态表⽰: dp[i][j]表⽰:到达[i, j]位置处,最⼩…...
React + TipTap 富文本编辑器 实现消息列表展示,类似Slack,Deepseek等对话框功能
经过几天折腾再折腾,弄出来了,弄出来了!!! 消息展示 在位编辑功能。 两个tiptap实例1个用来展示 消息列表,一个用来在位编辑消息。 tiptap灵活富文本编辑器,拓展性太好了!!! !!! 关键点&#x…...
博途 TIA Portal之1200做主站与汇川EASY的TCP通讯
前言,虽然已经做了几篇关于TCP通讯的文章,但是不同的PLC之间的配合可能不同,下面将演示这种差异。 关于汇川EASY做从站的配置请参见下方链接文章:汇川EASY系列之以太网通讯(套接字socket做从站)_汇川以太网tcp套接字fb块-CSDN博客 1、硬件准备: 1200PLC,汇川EASY320…...
蓝桥杯速成刷题清单(上)
一、1.排序 - 蓝桥云课 (快速排序)算法代码: #include <bits/stdc.h> using namespace std; const int N 5e5 10; int a[N];int main() {int n;cin >> n;for (int i 0; i < n; i) {cin >> a[i];}sort(a, a n);for …...
力扣第444场周赛
这次力扣周赛对我来说难度确实大, 只做出两题, 但还是想分享一下的做题经验和感受 1. 移除最小数对使数组有序 I 题目链接:力扣 给你一个数组 nums,你可以执行以下操作任意次数: 选择 相邻 元素对中 和最小 的一对。如果存在多个这样的对&a…...
Redis 持久化机制详解:RDB/AOF 过程、优缺点及配置。Redis持久化中的Fork与Copy-on-Write技术解析。
Redis 持久化机制详解:RDB/AOF 过程、优缺点及配置 一、RDB 持久化过程及特性 核心机制 生成快照:通过 fork 子进程生成内存数据的二进制快照文件(.rdb),父进程继续处理请求。写时复制(Copy-On-Write&…...
Go并发背后的双引擎:CSP通信模型与GMP调度|Go语言进阶(4)
为什么需要理解CSP与GMP? 当我们启动一个Go程序时,可能会创建成千上万个goroutine,它们是如何被调度到有限的CPU核心上的?为什么Go能够如此轻松地处理高并发场景?为什么有时候我们的并发程序会出现奇怪的性能瓶颈&…...
docker内安装达梦8数据库
1. 其他机器上实现挂载ISO # 1. 确保挂载点目录存在(你已经创建了dm8目录) ls -ld dm8# 2. 使用正确的mount命令挂载ISO sudo mount -o loop dm8_20250117_HWarm920_kylin10_sp1_64.iso dm8# 3. 验证是否挂载成功 mount | grep dm8 ls dm82. docker内运…...
UDP怎么样实现可靠传输?
如果需要在基于UDP的应用中实现可靠传输(例如确保数据不丢失、按顺序到达等),通常需要在应用层实现相应的机制。 1. 确认应答机制 应用层可以使用确认应答机制来确保数据的可靠传输。当发送方发送一个数据包时,接收方收到数据包…...
代码随想录算法训练营Day25
一、力扣93.复原IP地址【medium】 题目链接:力扣93.复原IP地址 left x300 视频链接:代码随想录 1、思路 时间复杂度: O ( n ) O(n) O(n) 2、代码 class Solution:def restoreIpAddresses(self, s: str) -> List[str]:n len(s)ans []…...
Linux服务器——Samba服务器
简介 Samba 是一个开源的跨平台文件共享服务,允许 Linux/Unix 系统与 Windows 系统实现文件和打印机的共享与互操作。其核心协议为 SMB/CIFS(Server Message Block / Common Internet File System),是 Windows 网络中…...
