[英]Unable to connect pyqtSignal with pyQtSlot - PyQt5 and Python 3.5
尝试使用 QThread 和 PyQt5 的插槽/信号来处理后台线程中的多个文件。
我在 PyQt5.8.2 中使用 Python 3.5.2。 PyCharm 2017.1 给了我以下警告:
w.done.connect(..)
的connect
部分的# FAILS HERE
行Unresolved attribute reference
Cannot find reference 'connect' in 'function'
在thread.started.connect(...)
Cannot find reference 'connect' in 'function'
。 当我尝试在 PyCharm 之外运行时,我得到TypeError: decorated slot has no signature compatible with Worker.done[]
。 在 PyCharm 中查看选项卡完成时,没有显示connect()
或disconnect()
方法,但emit()
有。 SO上的所有教程和问题都说以下应该有效。
简化后的代码是:
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QThread
from PyQt5.QtWidgets import QMainWindow
class MyApp(QMainWindow, myUiMainWindow):
def __init__(self):
super(self.__class__, self).__init()
self.setupUI(self)
@pyqtSlot()
def update_this(self):
<update things>
def doMyStuff(self):
<get a file_list>
for f in file_list:
w = Worker(f)
thread = QThread()
w.moveToThread(thread)
w.done.connect(self.update_this) # FAILS HERE
thread.started.connect(w.process) # FAILS HERE
thread.start()
class Worker(QObject):
done = pyqtSignal()
def __init__(self, file_path):
super(Worker, self).__init__(parent=None)
self.f = file_path
@pyqtSlot()
def process(self):
<do stuff>
self.done.emit()
更新:通过卸载 pyqt5 并从这里重新安装(anaconda.org/bpentz/pyqt5),我终于能够解决这个问题。 我不知道这是如何解决这个问题的,但确实如此。 但是,这段代码不起作用,它几乎立即关闭了 QThread()。 我更新了以下相关代码(如下),现在我在终端或 PyCharm 中没有回溯的 python 崩溃(奇怪的是,这在调试器中工作得很好)。 目标是遍历文件并在多个 QThreads() 中处理它们,更新进度条 (update_this),然后在处理完所有文件时提醒用户。
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QThread
from PyQt5.QtWidgets import QMainWindow
class MyApp(QMainWindow, myUiMainWindow):
def __init__(self):
super(self.__class__, self).__init()
self.setupUI(self)
self.pushButton.clicked.connect(self.doMyStuff)
@pyqtSlot()
def thread_complete(self):
self.num_completed += 1
if self.num_completed == len(self.file_list):
<reset things>
def doMyStuff(self):
<get a self.file_list>
self.num_completed = 0
self.threads = []
for f in self.file_list:
w = Worker(f)
self.threads.append(QThread())
w.moveToThread(threads[-1])
self.threads[-1].started.connect(w.process)
self.threads[-1].finished.connect(self.thread_complete)
self.threads[-1].start()
class Worker(QObject):
def __init__(self, file_path):
super(Worker, self).__init__(parent=None)
self.f = file_path
@pyqtSlot()
def process(self):
<do stuff with self.f>
附加更新:如前所述,问题不是将工作人员保留在内存中。 完成此操作后,线程方案就起作用了。 然而,同样如前所述,使用 QThread() 并没有实现我正在寻找并认为 QThreading 可能实现的多处理效率的想法,并且比仅仅在单个 QThread() 中串行处理文件更糟糕。 在尝试使用mutliprocessing引发其他的问题在这里。
工作 QThread() 代码(虽然很慢!):
def doMyStuff(self):
<get a self.file_list>
self.num_completed = 0
self.threads = []
self.workers = []
for f in self.file_list:
w = Worker(f)
w.done.connect(self.update_this)
thread = QThread()
w.moveToThread(thread)
thread.started.connect(w.process)
thread.finished.connect(self.thread_complete)
self.threads.append(thread)
self.workers.append(worker)
你应该直接继承 QThread
class WorkerThread(QThread):
def __init__(self, data):
super(WorkerThread, self).__init__()
self.setTerminationEnabled(True)
self.start()
def run(self):
pass
#do work here
您可以将一个插槽连接到此对象,线程会发出“已完成”
myworker = WorkerThread(data)
myworker.finished.connect(doWhatYouWant)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.