![](/img/trans.png)
[英]How to postpone execution of the QRunnable until signal from previous is emitted
[英]In PyQT how to store data emitted from signal in QRunnable
我在使用Python3的PyQT4應用程序中花了一段時間。 所以我一直在研究使用線程加速它。 數據很容易被破壞並循環處理。 我正在使用自定義QRunnable
,您可以在其中傳遞目標函數和args,然后將其饋送到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()
只是為了看看,但是按預期沒有幫助。
那么,組裝每個工人的數據輸出的正確方法是什么? 我想提出一個后續問題,即如何確保以正確的順序放回原位。
我的代碼之一遇到了類似的問題(也可能與此問題有關: 從QRunnable發出信號 )。
與您的情況一樣,已執行QRunnable
的操作,但結果未添加到結果列表中。 在另一篇文章中的答案說這是因為沒有調用主事件循環(使用app.exec_()
類的東西)。 我想在您的情況下是因為您嘗試在調用app.exec_()
)之前打印返回的結果(為空)(我可能已經閱讀了QThread或QRunnable的事件/信號已排隊,或在exec_
調用之前進行了exec_
?即使在您的情況下,也可以從回調函數中打印接收到的每個結果。
我想一個變通可能是創建一個QEventLoop
這將processEvents
從的工人QThreadPool
,那么當它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
成功使用了類似的模式)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.