python - PyQt5;使用 QRunnable 和 QThreadPool 的线程问题
问题描述
似乎我在我的应用程序中运行线程时遇到如下问题:在我的 MainForm 类中,我有:
.
.
self.threadPool = QtCore.QThreadPool()
self.threadPool.setMaxThreadCount(4)
.
.
def openFileFcn(self):
worker = **Worker**(self, **self.ImageViewer.showImages**, self.files)
self.threadPool.start(worker)
其中Worker是一个包装器 QRunnable,定义为:
class Worker(QtCore.QRunnable):
def __init__(self, fn, *args, **kwargs):
QtCore.QRunnable.__init__(self)
self.fn = fn
self.args = args
self.kwargs = kwargs
def run(self) -> None:
self.fn(*self.args, **self.kwargs)
而self.ImageViewer.showImages指的是 ImageViewer 类的以下部分:
def loadImg(self, file):
tabName = str()
if len(file) > 15: tabName = file[0:13] + "..."
widget = ImageViewer()
localPath = os.path.abspath(file)
localPath = QtCore.QDir().filePath(localPath)
pixmap = QtGui.QPixmap(localPath)
widget.setImage(pixmap)
self.tabwidget.addTab(widget, self.mainFormHandle.sharedData.imgIcon, tabName)
self.tabwidget.setCurrentIndex(self.tabwidget.currentIndex() + 1)
def **showImages**(self, files):
files = [file.lower() for file in files]
for file in files:
self.loadImg(file)
当我运行这段代码时,什么都没有发生。它只是冻结,一段时间后应用程序以退出代码 -1073740791 (0xC0000409) 关闭。你认为是什么原因?
解决方案
问题似乎是您试图从主线程之外的另一个线程创建小部件。您只能从主线程创建小部件,但由于loadImg()
创建了多个小部件,因此从线程池调用它会使您的应用程序崩溃。解决这个问题的一种方法是loadImg()
分成两种方法,一种方法是加载像素图,另一种方法是创建ImageViewer
s 并添加选项卡。然后可以将第一个移到线程池中,并且您可以使用信号在每次加载像素图时自动调用第二个。例如:
class TabArea(QtWidgets.QWidget):
pixmap_loaded = QtCore.pyqtSignal(str, QtGui.QPixmap)
def __init__(self, parent=None):
...
self.pixmap_loaded.connect(self.addTab)
def loadImg(self, file):
localPath = os.path.abspath(file)
localPath = QtCore.QDir().filePath(localPath)
pixmap = QtGui.QPixmap(localPath)
# emit pixmap and file name
self.pixmap_loaded.emit(file, pixmap)
def addTab(self, file, pixmap):
tabName = str()
if len(file) > 15: tabName = file[0:13] + "..."
widget = ImageViewer()
widget.setImage(pixmap)
self.tabwidget.addTab(widget, self.mainFormHandle.sharedData.imgIcon, tabName)
self.tabwidget.setCurrentIndex(self.tabwidget.currentIndex() + 1)
def showImages(self, files):
files = [file.lower() for file in files]
for file in files:
self.loadImg(file)
推荐阅读
- visual-studio-code - 保存编辑器布局
- r - 如何在 R 中抓取 PDF 的所有页面?
- html - 为什么我的 div 没有出现在我的主 div 中?
- angular - How to use button value for filter pipes in Angular
- python - 为什么使用 KivyMD 模块时应用程序会崩溃?
- javascript - 未传递函数参数。如何正确地将参数传递给另一个 JavaScript 文件的函数?
- java - isSelected() 不适用于硒中的单选按钮
- django - Django Rest Framework:使用视图集时添加“收藏/喜欢/评分”功能的 URL 端点?
- mongodb - Kotlin 数据类的 MongoDB CodecConfigurationException
- docker-compose - Docker compose:MariaDB 在 init.sql / entrypoint 出现错误