当前位置: 首页 > news >正文

Qt小组件 - 5 图片懒加载样例

加载本地大图片会有卡顿现象,因为imageLabel是同步加载

imageLabelQt小组件 - 3 imageLabel

Qt小组件 - 2(布局)瀑布流布局,GridLayout,FlowLayout

LoadImageThread最好使用线程池代替否则创建线程过多阻碍主线程刷新

# coding: utf-8
import sys
from pathlib import Path
from typing import List, Unionfrom PySide6.QtCore import QRect, QThread, Signal, Qt, QThreadPool, QTimer
from PySide6.QtGui import QImage, QPixmap
from PySide6.QtWidgets import QVBoxLayout, QApplication, QScrollArea, QWidgetfrom components import ImageLabel, WaterfallLayoutclass LoadImageThread(QThread):loadSignal = Signal(QImage)def __init__(self, parent=None):super().__init__(parent)self.url = Nonedef run(self):if not self.url:returnif isinstance(self.url, (str, Path)):url = str(self.url)image = QImage(url)else:image = self.urlself.loadSignal.emit(image)def setUrl(self, url):self.url = urlself.start()class LazyLoadThread(QThread):loadSignal = Signal(object, object)def __init__(self, parent=None):super().__init__(parent)self.isStopped = Falseself.rect = QRect()self.labels = []  # type: List[LazyLoadImage]def run(self):try:self.verify()except Exception as e:print(e)def setData(self, rect: QRect, labels: List['LazyLoadImage']):self.rect = rectself.labels = labelsself.start()def verify(self):viewport_rect: QRect = self.rectfor item in self.labels:item_rect = item.geometry()if viewport_rect.intersects(item_rect):self.loadSignal.emit(item, True)else:self.loadSignal.emit(item, False)def stop(self):self.isStopped = Trueself.terminate()class LazyLoadImage(ImageLabel):def _postInit(self):self.dataSource = Noneself.loadThread = LoadImageThread(self)self.loadThread.loadSignal.connect(self.setImage)self.finished.connect(self.on_finished)def setDataSource(self, source: str):self.dataSource = sourcedef setImageUrl(self, url: str):self.loadThread.setUrl(url)def setLoading(self, loading: bool):if loading and self.isNull():if self.dataSource.startswith('http'):self.setUrl(self.dataSource)else:self.setImageUrl(self.dataSource)else:if self.isNull():returnself.setImageUrl(QImage())class LazyLoadScrollArea(QScrollArea):def __init__(self, parent=None):super().__init__(parent)self.labels = []self.timer = QTimer(self) # 避免多次加载self.lazy_load_thread = LazyLoadThread(self)self.lazy_load_thread.loadSignal.connect(self.on_load_signal)self.setWidget(QWidget())self.widget().setLayout(WaterfallLayout())self.setWidgetResizable(True)self.verticalScrollBar().valueChanged.connect(self.start)self.timer.timeout.connect(self.updateLazy)self.timer.setSingleShot(True)self.timer.setInterval(150)def on_load_signal(self, item: LazyLoadImage, loading: bool):try:item.setLoading(loading)item.finished.connect(lambda: item.scaledToWidth(item.width()))except Exception as e:print(e)def start(self):self.timer.stop()self.timer.start()def updateLazy(self):rect = self.viewport().rect()rect.translate(self.horizontalScrollBar().value(), self.verticalScrollBar().value())self.lazy_load_thread.setData(rect, self.labels)self.updateGeometry()def add_image(self, url: str):image_label = LazyLoadImage()image_label.setDataSource(url)image_label.setScaledContents(True)image_label.setMinimumHeight(400)self.labels.append(image_label)layout = self.widget().layout()layout.addWidget(image_label)if layout.sizeHint().height() < self.height():self.start()def resizeEvent(self, event):self.start()super().resizeEvent(event)def closeEvent(self, event):self.lazy_load_thread.stop()self.timer.stop()super().closeEvent(event)if __name__ == "__main__":app = QApplication(sys.argv)scroll_area = LazyLoadScrollArea()scroll_area.setWindowTitle("图片懒加载示例")scroll_area.resize(400, 600)# 添加一些图片URL到滚动区域image_urls = ["http://browser9.qhimg.com/bdm/1024_632_0/t010824ab8b5cdfa138.jpg","http://browser9.qhimg.com/bdm/512_316_0/t010448c46c1ecf7cab.jpg","http://browser9.qhimg.com/bdm/1024_632_0/t013a4ed4683039d101.jpg"]for url in image_urls:scroll_area.add_image(url)for url in Path(r'G:\手机\壁纸\碧蓝航线\5.26立绘\Picture').glob('*.*'):scroll_area.add_image(url.as_posix())scroll_area.show()sys.exit(app.exec())

连续创建了2675个组件左右,初次打开需要10S左右的时间

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/281856.html

相关文章:

  • 【MAC】nacos 2.5.1容器docker安装
  • Python面向对象编程(OOP)详解:通俗易懂的全面指南
  • 高性能架构模式——高性能缓存架构
  • python的慈善捐赠平台管理信息系统
  • 【前端】在Vue3中绘制多系列柱状图与曲线图
  • rocky8 --Elasticsearch+Logstash+Filebeat+Kibana部署【7.1.1版本】
  • 阿奇霉素:长效广谱抗菌背后的药理特性与研发历程
  • 利用Java自定义格式,循环导出数据、图片到excel
  • excel分组展示业绩及增长率
  • 解锁高效Excel技能:摆脱鼠标,快速编辑单元格
  • java操作Excel两种方式EasyExcel 和POI
  • DHTMLX Suite 9.2 重磅发布:支持历史记录、类Excel交互、剪贴板、拖放增强等多项升级
  • HTML进阶
  • Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
  • 分布式弹性故障处理框架——Polly(1)
  • 卷积神经网络-卷积的分类
  • 数据结构与算法学习(一)
  • 从函数调用到进程通信:Linux下的多语言协作实践
  • STM32 | 定时器 PWM 呼吸灯
  • 坚持继续布局32位MCU,进一步完善产品阵容,96Mhz主频CW32L012新品发布!
  • 尚庭公寓-------图片上传接口
  • 推客系统开发:从零构建高并发社交平台的技术实践
  • Python爬虫实战:研究PyYAML库相关技术
  • 多维动态规划题解——不同路径【LeetCode】递推写法空间优化
  • 【Qt开发】Qt的背景介绍(二)-> 搭建Qt开发环境
  • 从混沌到秩序:数据科学的热力学第二定律破局——线性回归的熵减模型 × 最小二乘的能量最小化 × 梯度下降的负反馈控制系统,用物理定律重构智能算法的统一场论
  • Blender 云渲染高效流程:渲染 101 集群加速实战​
  • 硬件产品的技术资料管控是确保研发可追溯、生产可复制、质量可控制的核心环节。
  • Linux 716 数据库迁移
  • NodeJS Express 静态文件、中间件、路由案例