【发布时间】:2016-12-07 19:44:36
【问题描述】:
我知道如何将信号从工作线程发送回主 GUI 线程,但是如何将信号从主线程发送到工作线程?
这是一些包含信号和槽的示例代码。在这里,我将信号发送回主线程,但我该如何反方向呢?
这里的目标是在我希望线程停止时发送一个信号将 self.do 的值更改为 0。
这里是主文件,我会把 UI 文件放在下面
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot
from progressUI import Ui_Form
import sys
import time
class ProgressBar(QObject):
progress = pyqtSignal(int)
kill = pyqtSignal()
def __init__(self, timer, parent=None):
super(ProgressBar, self).__init__(parent)
self.time = timer
self.do = 1
def work(self):
while self.do == 1:
y = 0
for _ in range(100):
time.sleep(.1)
y += 1
self.progress.emit(y)
break
self.kill.emit()
@pyqtSlot(str)
def worker_slot(self, sentence):
print(sentence)
class Go(QMainWindow, Ui_Form, QObject):
custom_signal = pyqtSignal(str)
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.setupUi(self)
self.progressBar.setValue(0)
self.startThread()
@pyqtSlot(int)
def updateProgress(self, val):
self.progressBar.setValue(val)
self.custom_signal.emit('hi from main thread')
def startThread(self):
self.progressThread = ProgressBar(60)
self.thread = QThread()
self.progressThread.moveToThread(self.thread)
self.progressThread.progress.connect(self.updateProgress)
self.progressThread.kill.connect(self.thread.quit)
self.custom_signal.connect(self.progressThread.worker_slot)
self.thread.started.connect(self.progressThread.work)
self.thread.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainApp = Go()
MainApp.show()
sys.exit(app.exec_())
这是 UI 文件。
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(658, 118)
self.progressBar = QtWidgets.QProgressBar(Form)
self.progressBar.setGeometry(QtCore.QRect(30, 40, 601, 23))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(45, 75, 581, 26))
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "TextLabel"))
【问题讨论】:
-
您的代码无法运行。存在拼写错误,我们无法访问您的 UI。
-
不,它没有运行代码。这是一个示例供您查看。
-
好的,所以我看了一下,我发现......它不起作用。无论如何,是什么阻止您向工作人员发送信号?
-
请参阅stackoverflow.com/a/35534047/1994235,但请注意,您不能在工作人员中拥有一个永远循环的函数,因为这会阻止工作人员处理信号。用其他东西替换循环(比如
QTimer,但要确保它存在于正确的线程中——那里有一些微妙之处) -
@squirtgun 我不确定为什么链接不是您要找的。主线程中的信号是带有
QPushButton的clicked信号。随意使用主线程中存在的任何预先存在的信号,或者在位于主线程中的QObject中定义一个新信号。 slot 是 worker 函数中的一个方法。因此,信号从主线程发出并调用工作函数中的一个槽。这不是你要找的吗?该示例显示了主线程和工作线程之间的双向通信。不确定您还想要什么?
标签: python qt python-3.x pyqt pyqt5