Python在两个QThread之间发送信号
我无法从一个qthread向另一个qthread发送信号。我正在使用的类似代码摘录如下:Python在两个QThread之间发送信号,python,pyqt,signals,qthread,Python,Pyqt,Signals,Qthread,我无法从一个qthread向另一个qthread发送信号。我正在使用的类似代码摘录如下: class auth(QtCore.QThread): authenticate = pyqtSignal() serverDown = pyqtSignal() accntonline = pyqtSignal() def __init__(self, parent=None): super(auth, self).__init__(parent)
class auth(QtCore.QThread):
authenticate = pyqtSignal()
serverDown = pyqtSignal()
accntonline = pyqtSignal()
def __init__(self, parent=None):
super(auth, self).__init__(parent)
def run(self):
self.authenticate.emit()
class Threadclass(QtCore.QThread):
authenticator = "n"
def __init__(self, parent=None):
super(Threadclass, self).__init__(parent)
#setting first values avoiding errors
self.a = auth(self)
self.a.authenticate.connect(self.setauthentication)
#All small functions setting values from box.
def setauthentication(self):
print("awdawdawda")
self.authenticator = "y"
当我运行线程auth时,变量self.authenticator
不会改变。它停留在“n”处。
如果覆盖
QThread
的run
方法,则除非显式调用其exec
方法,否则它不会启动自己的事件循环。处理交叉线程信号需要事件循环。因此,通常最好创建一个worker对象并将其移动到线程,而不是重写run
下面是一个演示脚本,演示如何将辅助对象与线程一起使用:
import sys
from PyQt5 import QtWidgets, QtCore
class AuthWorker(QtCore.QObject):
authenticate = QtCore.pyqtSignal()
def __init__(self):
super(AuthWorker, self).__init__()
def run(self):
QtCore.QThread.sleep(0.5)
self.authenticate.emit()
class Worker(QtCore.QObject):
finished = QtCore.pyqtSignal(str)
authenticator = "n"
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
self.auth = AuthWorker()
self.auth_thread = QtCore.QThread()
self.auth.moveToThread(self.auth_thread)
self.auth.authenticate.connect(self.setauthentication)
self.auth_thread.started.connect(self.auth.run)
def setauthentication(self):
self.authenticator = "y"
def run(self):
self.auth_thread.start()
QtCore.QThread.sleep(1)
self.finished.emit('auth: %s' % self.authenticator)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.button = QtWidgets.QPushButton('Test', self)
self.button.clicked.connect(self.handleButton)
self.edit = QtWidgets.QLineEdit(self)
self.edit.setReadOnly(True)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.button)
self.thread = QtCore.QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.worker.finished.connect(self.handleFinished)
self.thread.started.connect(self.worker.run)
def handleFinished(self, text):
self.thread.quit()
self.edit.setText(text)
def handleButton(self):
if not self.thread.isRunning():
self.edit.clear()
self.thread.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 200, 100)
window.show()
sys.exit(app.exec_())
如果覆盖
QThread
的run
方法,则除非显式调用其exec
方法,否则它不会启动自己的事件循环。处理交叉线程信号需要事件循环。因此,通常最好创建一个辅助对象并将其移动到线程,而不是覆盖run
@ekhumoro有用信息。您是否可以使用我给出的代码提供一个示例?我已经根据您的示例代码添加了一个答案。希望您能看到如何调整它以在实际应用程序中使用。我认为这几乎解决了问题,但如何从另一个窗口(按下按钮的gui信号调用线程运行)调用这些线程@Kermit。我已经扩展了我的代码示例,以显示线程和一个简单gui之间的通信。@ekhumoro您将在何处实现例如多处理和与主gui通信?创建单独的类并通过Qthread从Window类调用它?或者在下执行,如果
?后者避免包含在GUI的事件循环中)。(顺便说一句:我可以想象这将是一个单独的问题。只要让我知道一个我会像这样发布它,并引用这个问题)。@ZF007请开始一个新问题。