PySide6批量创建控件

最近闲的没事写了个漫画爬虫,但在下载的时候出现了问题,有些漫画100多章还好,有的3000章,这就需要连续创建3000个组件,而在创建组件时会直接卡死主界面。

提供两种解决方法。

1. 多线程

将循环放到其他线程,不在同一个时间点创建

python 复制代码
from PySide6.QtWidgets import QScrollArea, QWidget, QGridLayout, QLabel, QApplication

from collections import deque

from PySide6.QtCore import QThread, Signal


class ListLoadThread(QThread):
    signal = Signal(object, object)  # 函数,参数

    def __init__(self, parent=None):
        super().__init__(parent)
        self.queue = deque()

        self.signal.connect(self._handle_callback)

    def _handle_callback(self, func, item):
        if func:
            func(item)

    def run(self):
        while self.queue:
            items, func = self.queue.popleft()
            for item in items:
                self.msleep(30)
                self.signal.emit(func, item)

    def addItem(self, items: list, func: object):
        self.queue.append((items, func))
        if not self.isRunning():
            self.start()


class ScrollArea(QScrollArea):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.scrollWidget = QWidget()
        self.loadThread = ListLoadThread(self)
        self.startBtn = QPushButton("Start", self)
        self.scrollLayout = QGridLayout(self.scrollWidget)

        self.setWidget(self.scrollWidget)
        self.setWidgetResizable(True)
        self.setViewportMargins(10, 30, 10, 10)
        self.scrollLayout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignHCenter)

        self.startBtn.clicked.connect(self.start)

    def start(self):
        self.loadThread.addItem([i for i in range(100000)], self.add_item)

    def add_item(self, item):
        label = QLabel(f'Label {item}', self.scrollWidget)
        count = self.scrollLayout.count()
        self.scrollLayout.addWidget(label, count // 6, count % 6)


if __name__ == '__main__':
    app = QApplication([])
    window = ScrollArea()
    window.show()
    app.exec()
2. 异步

试了一下3000个是不卡的,数量再多也是会卡的,超过3000时,还是使用多线程好点

python 复制代码
pip install qasync 
python 复制代码
import asyncio
import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QWidget, QApplication, QPushButton, QLabel, QScrollArea, QGridLayout
from qasync import QEventLoop, asyncSlot


class MainWindow(QScrollArea):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.scrollWidget = QWidget()
        self.startBtn = QPushButton("Start", self)
        self.scrollLayout = QGridLayout(self.scrollWidget)

        self.setWidget(self.scrollWidget)
        self.setWidgetResizable(True)
        self.setViewportMargins(10, 30, 10, 10)
        self.scrollLayout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignHCenter)

        self.startBtn.clicked.connect(self.start_scroll)

    async def add_item(self, item):
        label = QLabel(f'Label {item}', self.scrollWidget)
        count = self.scrollLayout.count()
        self.scrollLayout.addWidget(label, count // 6, count % 6)

    @asyncSlot()
    async def start_scroll(self):
        for i in range(1000):
            await self.add_item(i)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    loop = QEventLoop(app)
    asyncio.set_event_loop(loop)

    window = MainWindow()
    window.show()
    sys.exit(loop.run_forever())
相关推荐
bamb0015 分钟前
一个项目带你入门AI应用开发05
python
Python私教16 分钟前
Django 6.1 邮件配置大改:旧项目如何平稳升级?
后端·python·django
Python私教19 分钟前
Django 6.1 升级避坑:数据库版本不兼容怎么解决?
后端·python·django
Python私教19 分钟前
Django 接口开发实测:新手还需要使用 REST 框架吗?
后端·python·django
名字还没想好☜1 小时前
Python concurrent.futures 实战:用 ThreadPoolExecutor 并发处理 + as_completed 收结果
数据库·python·php·并发
爱码小白1 小时前
importlib模块
开发语言·前端·python
axinawang1 小时前
第25课 for循环的应用
python
逻极2 小时前
FastAPI 实战:从入门到自动化文档,如何把API开发效率提升200%
python·api·fastapi·swagger·异步
半兽先生2 小时前
大模型技术开发与应用——5.大模型Agent开发(CrewAI)
大数据·人工智能·python·机器学习·ai