pyqt 多线程:为什么工作线程阻塞主线程

时间:2021-06-15 12:54:48

标签: python pyqt pymupdf

当我尝试加载一些 size>10MB 或 pages>300 的 .pdf 时,

工作线程会阻塞主线程,我不知道如何正确使用QThread

我希望每次 pixmap_page_load 运行时,都将信号发送到主线程。

这里是最少的代码,需要模块pymupdf和一个pdf文件

import time

from PyQt5.QtCore import QRectF, Qt, pyqtSignal, QThread
from PyQt5.QtGui import QColor, QBrush, QPen, QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QMainWindow, QGraphicsScene, QGraphicsView, QGraphicsItem, \
    QFileDialog

from fitz import fitz

def pixmap_page_load(doc:"fitz.Document", pagenum, ratio=1):

    page:"fitz.Page" = doc.load_page(pagenum)  # 加载的是页面
    pix:"fitz.Pixmap" = page.getPixmap(matrix=fitz.Matrix(ratio, ratio))  # 将页面渲染为图片
    fmt = QImage.Format_RGBA8888 if pix.alpha else QImage.Format_RGB888  # 渲染的格式

    pageImage = QImage(pix.samples, pix.width, pix.height, pix.stride, fmt)
    pixmap = QPixmap()
    pixmap.convertFromImage(pageImage)  # 转为pixmap
    return QPixmap(pixmap)

class MyGraphicRect2(QGraphicsItem):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.setPos(self.x, self.y)
        self.color = QColor('red')

        self.setAcceptDrops(True)
        self.setCursor(Qt.OpenHandCursor)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QGraphicsItem.ItemIsFocusable, True)
        self.setAcceptHoverEvents(True)

    def setColor(self, color):
        self.color = QColor(color)

    def boundingRect(self):
        return QRectF(self.x, self.y, self.width, self.height)

    def paint(self, painter, options, widget):
        painter.setPen(QPen(QColor('black')))
        painter.setBrush(self.color)
        painter.drawRect(self.x, self.y, self.width, self.height)


class MoveThread(QThread):
    s = pyqtSignal(float, float)
    def __init__(self,directory):
        super().__init__()
        self.directory=directory
    def run(self):

        doc= fitz.open(self.directory)
        for i in range(1,len(doc)):
            pixmap = pixmap_page_load(doc,i)
            self.s.emit(i,0)


class MyGraphicScene(QMainWindow):
    def __init__(self):
        super().__init__()
        self.rect=QRectF(0,0,800,800)
        self.Scene=QGraphicsScene(self.rect)
        self.View=QGraphicsView()
        self.View.setCacheMode(QGraphicsView.CacheNone)
        self.sceneConfig()
        self.displayUI()

    def sceneConfig(self):
        self.Scene.setBackgroundBrush(QBrush(QColor('yellow'),Qt.SolidPattern))

        self.item1=MyGraphicRect2(100,100,100,100)
        self.Scene.addItem(self.item1)
        line=QGraphicsLineItem(80,38,84,38)
        self.Scene.addItem(line)
        self.View.setScene(self.Scene)

    def updatePosition(self, x, y):
        item1 = MyGraphicRect2(100+x, 100+y, 100, 100)
        self.Scene.addItem(item1)

    def displayUI(self):
        print('Is scene active', self.Scene.isActive())
        directory, _ = QFileDialog.getOpenFileName(None, "选取文件", ".", "(*.pdf)")
        self.setCentralWidget(self.View)
        self.th=MoveThread(directory)
        self.th.s.connect(self.updatePosition)
        self.th.start()
        self.resize(1000,1000)
        self.show()

if __name__ == "__main__":
    import sys
    app=QApplication(sys.argv)

    m=MyGraphicScene()

    sys.exit(app.exec_())

0 个答案:

没有答案
相关问题