gpt4 book ai didi

python - 在 PyQT 中如何存储 QRunnable 中信号发出的数据

转载 作者:太空宇宙 更新时间:2023-11-03 17:31:02 24 4
gpt4 key购买 nike

我有一个在使用 Python3 的 PyQT4 应用程序中需要一段时间的过程。所以我一直在研究使用线程来加速它。数据可以很容易地被分解并循环处理。我正在使用自定义的 QRunnable,您可以在其中传递目标函数和参数,然后将其输入到 QThreadpool 中。我使用 pyqtSignal 来发出每个工作人员处理后的数据。我的插槽正在接收数据,但未存储数据。下面是我尝试过的简化示例。

import sys, time
from random import uniform
from PyQt4 import QtCore, QtGui

class AWorker(QtCore.QRunnable):
""" Generic Task for ThreadPool to execute required Kwargs =
target (<function>): function to call
args (tuple): args for target
kwargs (dict): kwargs for target """
def __init__(self, target=None, args=(), kwargs={}):
super(AWorker, self).__init__()
self.target = target
self.args = args
self.kwargs = kwargs
def run(self):
self.target(*self.args, **self.kwargs)

class myTest(QtCore.QObject):

doneSignal = QtCore.pyqtSignal(int) #Create a signal to emit the data

def __init__(self):
super(myTest, self).__init__()
self._procData = [] #Place to Store data .. maybe
self.pool = QtCore.QThreadPool.globalInstance()
self.pool.setMaxThreadCount(4) #Use up to 8 threads

def runAll(self):
self.doneSignal.connect(self.storeData)
for data in range(4):
worker = AWorker(target=self.processData, args=(data,))
self.pool.start(worker)

def processData(self,data):
print('Crunching ...', str(data))
outData = data+10
time.sleep(uniform(1,3)) #Simulate this taking a random amount of time
self.doneSignal.emit(outData)

def storeData(self,data):
print('Received ...', str(data))
self._procData.append(data)

def getData(self):
return self._procData

if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
test = myTest()
test.runAll()
test.pool.waitForDone()
print('All done ... and the data is: ',test.getData())
app.exec_()

它运行并打印出以下内容:

Crunching ... 0
Crunching ... 1
Crunching ... 3
Crunching ... 2
All done ... and the data is: []
Received ... 13
Received ... 11
Received ... 12
Received ... 10

好的,那么信号在全部完成后才会发出?或许?或者我无法分配给 _procData 因为我在不同的线程中或其他什么?我尝试删除 waitForDone() 只是为了看看,但正如预期的那样并没有帮助。

那么组装每个工作人员的数据输出的正确方法是什么?我想一个后续问题是,如何确保它按正确的顺序放回。

最佳答案

我的代码之一遇到了类似的问题(也可能与此问题相关: Emitting signals from a QRunnable )。
正如您的情况一样,QRunnable 中的操作已执行,但结果未附加在结果列表中。另一篇文章中的答案说这是因为主事件循环没有被调用(使用诸如 app.exec_() 之类的东西)。我猜在你的情况下,这是因为你在调用 app.exec_() 之前尝试打印返回的结果(为空)(我可能已经读到来自 QThread 或 QRunnable 的事件/信号已排队或其他什么)就像在 exec_ 调用之前一样?即使在您的情况和我的情况一样,收到的每个单独结果都可以从回调函数中打印)。

我猜想解决方法可能是创建一个QEventLoop,它将从QThreadPool的工作线程中processEvents,然后当它exit() 所有信号/事件均已处理。使用您的代码,它可能看起来像:

def runAll(self):
self.eventloop = QEventLoop()
self.pool = QtCore.QThreadPool.globalInstance()
self.pool.setMaxThreadCount(4)
self.doneSignal.connect(self.storeData)
for data in range(4):
worker = AWorker(target=self.processData, args=(data,))
self.pool.start(worker)
self.pool.waitForDone()
self.eventloop.processEvents()
self.eventloop.exit()
# Now your data should have been appended to your list

(我没有测试这段代码,但我成功地对我的一些 QThreadPool 使用了类似的模式)

关于python - 在 PyQT 中如何存储 QRunnable 中信号发出的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31844736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com