python - pyqt多线程:为什么工作线程阻塞主线程
问题描述
当我尝试加载一些size
>10MB 或pages
>300 的 .pdf 时,
worker线程会阻塞主线程,不知道怎么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_())
解决方案
推荐阅读
- csv - 用于将 xlsb 转换为 csv 的 Nifi 处理器
- html - 添加网站图标 -
不是 - workflow - 设置字段值工作流
- javascript - 如何在javascript中将数字格式更改为字母月份
- javascript - Youtube Iframe API 多个视频使用自定义按钮开始每个视频
- java - 如何关闭在 startActivityForResult 上打开的意图
- c# - .NET Framework 与 .NET Core - 将证书添加到 RESTful API 调用中的一个,而不是另一个
- python - 优化距离矩阵计算
- javascript - Amchart:绘制不同时区的图表(例如浏览器时区 = 美国/多伦多,图表目标时区 = 美国/芝加哥)
- flutter - Flutter 中的 webRTC 视频和音频调用