Python PyQt5在QThread

问题描述

所以我有这个UI加载了很多按钮,所有按钮都带有图像,问题是,它花了很长时间,所以我尝试将其放到QThread中,虽然它可以正常工作,但是速度不高差异,所以我尝试了不同的解决方案,但现在线程无法启动。

代码

import sys
import os
from PyQt5 import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import QtCore,QtGui,QtPrintSupport,QtWidgets,uic

# I've tried using a QThread for this,but it still took the same amount of time.
class LoadImageThumbnailshread(QThread):
    def __init__(self,listButtons,listPaths):
        QThread.__init__(self)
        self.listButtons = listButtons
        self.listPaths = listPaths

    def run(self):
        self.process_images_Thread()

    def process_images_Thread(self):
        for i,j in enumerate(self.listButtons):
            j.setIcon(QIcon(self.listPaths[i]))
            j.setIconSize(QSize(150-6,60-6))


class App(QDialog):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 layout - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 320
        self.height = 100
        self.images_path = []
        self.button_images = []
        self.initUI()

    def initUI(self):
        self.setwindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)

        self.createGridLayout()

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(windowLayout)

        self.show()

    def createGridLayout(self):
        self.horizontalGroupBox = qgroupbox("Grid")
        layout = qgridLayout()
        layout.setColumnStretch(1,4)
        layout.setColumnStretch(2,4)

        for i in range(100):
            self.btnImage = QPushButton()
            self.btnImage.setobjectName('btnImage')
            self.images_path.append(os.path.dirname(
                os.path.abspath(__file__)) + 'view.png')

            # ! I have also tried using pixmaps with Clickable labels,but it made no diffrence.
            # pixmap = Qpixmap(os.path.dirname(os.path.abspath(__file__)) + image_locations[i])
            # pixmap = pixmap.scaled(60,300,Qt.KeepAspectRatio,Qt.FastTransformation)
            # self.btnImage.setpixmap(pixmap)

            # ! Enableing this loads the images,but very slowly
            # self.btnImage.setIcon(QIcon(os.path.dirname(os.path.abspath(__file__)) + '/view.png'))
            # self.btnImage.setIconSize(QSize(150-6,60-6))
            self.button_images.append(self.btnImage)
            layout.addWidget(self.btnImage,i,0)

        # ! This starts the QThread
        converter = LoadImageThumbnailshread(
            self.button_images,self.images_path)
        converter.start()
        self.horizontalGroupBox.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

因此,为了解释我想要的更多内容,我想在加载UI之后启动QThreadQThread将把所有图像加载到每个按钮上。问题是:它现在不起作用。

我遇到的另一个问题是,当我收到QThread时,UI等待其完成,然后突然弹出所有内容。我希望QThread完全独立且美观,如果可以的话,可以看到所有图像一张一张地加载。

解决方法

线程不用于加速任何任务!而是用于执行不阻塞任何线程的任务。鉴于上述情况,如果我有n个“任务”,并且每个任务都在“ n”个线程中执行,则总执行时间将为1个任务,也就是说,没有任务被加速,而是重新分配了任务。结论:如果要加速任务,则线程不是默认选项,因为它取决于应用程序。

另一方面,映像的加载不会消耗时间,但是有许多任务消耗的时间很少,总的来说,这相当于一个消耗大量时间的任务,不幸的是,该任务无法在另一个线程中执行或过程,因为GUI的元素不是线程安全的。

一种解决方法是,每T秒负载由n个元素组成的一小组,因此总任务将被分配,并且用户将不会观察到任何滞后效应。

import os
import sys

from PyQt5.QtCore import QSize,QTimer
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
    QApplication,QDialog,QGridLayout,QGroupBox,QPushButton,QVBoxLayout,)


class App(QDialog):
    def __init__(self):
        super().__init__()
        self.title = "PyQt5 layout - pythonspot.com"
        self.left = 10
        self.top = 10
        self.width = 320
        self.height = 100
        self.images_path = []
        self.button_images = []
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left,self.top,self.width,self.height)

        self.createGridLayout()

        windowLayout = QVBoxLayout(self)
        windowLayout.addWidget(self.horizontalGroupBox)

        self._iter = iter(range(100))
        self._timer = QTimer(interval=10,timeout=self.lazy_loading)
        self._timer.start()

    def createGridLayout(self):
        self.horizontalGroupBox = QGroupBox("Grid")
        self.grid_layout = QGridLayout()
        self.grid_layout.setColumnStretch(1,4)
        self.grid_layout.setColumnStretch(2,4)
        self.horizontalGroupBox.setLayout(self.grid_layout)

    def lazy_loading(self):
        try:
            i = next(self._iter)
        except StopIteration:
            self._timer.stop()
        else:
            btn = QPushButton()
            image_path = os.path.join(os.path.abspath(__file__),"view.png")
            btn.setIcon(QIcon(image_path))
            btn.setIconSize(QSize(150 - 6,60 - 6))
            self.grid_layout.addWidget(btn,i,0)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...