当 PyQt4 中的 QRunners 的 QThreadPool 执行完成时得到通知
Get notification when QThreadPool of QRunners in PyQt4 have completed execution
我在 Python 2.7 上的 PyQt4 中一个接一个地 运行 QThreadPool 中的 QRunners 线程设置了这个快速而肮脏的测试。基本上它看起来 运行 没问题,但是 threads/pool 似乎不会在所有线程都完成执行后停止 QThreadPool。
我想知道它是否像在执行完代码后从 QRunnable(ProductImporter
此处)返回一些内置方法一样简单,但我似乎无法在文档中找到任何内容。
我正在将一些代码从 QThread 结构转移到此设置中,因为我不能同时拥有并发线程 运行。
关于如何让 ProductImportTasks 知道它的任务已全部完成,以便我可以在之后执行更多代码,或者在 class 被调用之后有什么想法吗?任何帮助将不胜感激!
import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QThreadPool, QObject, QRunnable, pyqtSignal
class WorkerSignals(QObject):
productResult = pyqtSignal(str)
class ProductImporter(QRunnable):
def __init__(self, product):
super(ProductImporter, self).__init__()
self.product = product
self.signals = WorkerSignals()
def run(self):
self.signals.productResult.emit(self.product['name'])
return
class ProductImportTasks(QObject):
def __init__(self, products):
super(ProductImportTasks, self).__init__()
self.products = products
self.pool = QThreadPool()
self.pool.setMaxThreadCount(1)
def process_result(self, product):
return
def start(self):
for product in self.products:
worker = ProductImporter(product)
worker.signals.productResult.connect(view.text)
self.pool.start(worker)
self.pool.waitForDone()
class ViewController(QObject):
def __init__(self, parent=None):
super(ViewController, self).__init__(parent)
#@pyqtSlot(str)
def text(self, message):
print "This is the view.text method: " + message
return
if __name__ == "__main__":
app = QApplication(sys.argv)
view = ViewController()
main = ProductImportTasks([{"name": "test1"}, {"name": "test2"}, {"name": "test3"}])
main.start()
sys.exit(app.exec_())
这是您的脚本的作用:
- 调用
main.start()
- 创建可运行对象并启动线程池
- 等待所有可运行程序完成
- returns 来自
main.start()
- 启动应用程序事件循环
一旦事件循环开始,runnable 发出的信号将被处理,消息将被打印出来。这是因为默认情况下跨线程发送的信号是排队。通常,信号是同步发送的,不需要 运行 事件循环。
如果你改变信号的连接类型,并添加一些打印语句,应该清楚发生了什么:
worker.signals.productResult.connect(view.text, Qt.DirectConnection)
self.pool.start(worker)
self.pool.waitForDone()
print('finished')
...
main.start()
print('exec')
sys.exit(app.exec_())
我在 Python 2.7 上的 PyQt4 中一个接一个地 运行 QThreadPool 中的 QRunners 线程设置了这个快速而肮脏的测试。基本上它看起来 运行 没问题,但是 threads/pool 似乎不会在所有线程都完成执行后停止 QThreadPool。
我想知道它是否像在执行完代码后从 QRunnable(ProductImporter
此处)返回一些内置方法一样简单,但我似乎无法在文档中找到任何内容。
我正在将一些代码从 QThread 结构转移到此设置中,因为我不能同时拥有并发线程 运行。
关于如何让 ProductImportTasks 知道它的任务已全部完成,以便我可以在之后执行更多代码,或者在 class 被调用之后有什么想法吗?任何帮助将不胜感激!
import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QThreadPool, QObject, QRunnable, pyqtSignal
class WorkerSignals(QObject):
productResult = pyqtSignal(str)
class ProductImporter(QRunnable):
def __init__(self, product):
super(ProductImporter, self).__init__()
self.product = product
self.signals = WorkerSignals()
def run(self):
self.signals.productResult.emit(self.product['name'])
return
class ProductImportTasks(QObject):
def __init__(self, products):
super(ProductImportTasks, self).__init__()
self.products = products
self.pool = QThreadPool()
self.pool.setMaxThreadCount(1)
def process_result(self, product):
return
def start(self):
for product in self.products:
worker = ProductImporter(product)
worker.signals.productResult.connect(view.text)
self.pool.start(worker)
self.pool.waitForDone()
class ViewController(QObject):
def __init__(self, parent=None):
super(ViewController, self).__init__(parent)
#@pyqtSlot(str)
def text(self, message):
print "This is the view.text method: " + message
return
if __name__ == "__main__":
app = QApplication(sys.argv)
view = ViewController()
main = ProductImportTasks([{"name": "test1"}, {"name": "test2"}, {"name": "test3"}])
main.start()
sys.exit(app.exec_())
这是您的脚本的作用:
- 调用
main.start()
- 创建可运行对象并启动线程池
- 等待所有可运行程序完成
- returns 来自
main.start()
- 启动应用程序事件循环
一旦事件循环开始,runnable 发出的信号将被处理,消息将被打印出来。这是因为默认情况下跨线程发送的信号是排队。通常,信号是同步发送的,不需要 运行 事件循环。
如果你改变信号的连接类型,并添加一些打印语句,应该清楚发生了什么:
worker.signals.productResult.connect(view.text, Qt.DirectConnection)
self.pool.start(worker)
self.pool.waitForDone()
print('finished')
...
main.start()
print('exec')
sys.exit(app.exec_())