PyQt5:如何向工作线程发送信号 [英] PyQt5: How to send a signal to a worker thread

查看:379
本文介绍了PyQt5:如何向工作线程发送信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何将信号从工作线程发送回主 GUI 线程,但如何从主线程向工作线程发送信号?

I know how to send signals from worker threads back to the main GUI thread, but how can I send signals from the main thread to the worker thread?

这是一些示例代码,其中包括信号和槽.在这里,我将信号发送回主线程,但我怎么能往相反的方向走?

Here's some sample code which includes a signal and slot. Here I'm sending signals back to the main thread, but how can I go in the opposite direction?

这里的目标是当我希望线程停止时发送一个信号将 self.do 的值更改为 0.

The goal here being to send a signal to change the value of self.do to 0 when I want the thread to stop.

这是主文件,我将把 UI 文件放在下面

Here's the main file and I'll put the UI file below

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"))

推荐答案

如何向工作线程发送信号?与从工作线程向 GUI 发送信号的方式完全相同.我希望它会更加不同.

How do you send a signal to a worker thread? Exactly the same way as sending a signal from a worker thread to the GUI. I expected it to be more different.

@three-pineapples 链接到主线程和工作线程之间双向通信的一个很好的例子.

@three-pineapples linked to an excellent example of bi-directional communication between the main thread and a worker thread.

如果要在主 GUI 线程中创建自定义信号,则需要确保继承 QObject,然后才能创建自定义信号.

If you want to create a custom signal in the main GUI thread, you need to make sure you inherit QObject and then you'll be able to create custom signals.

我更新了原始帖子中的代码以包含 UI 文件,以便您可以运行它,并且我在 GUI 线程中包含了一个自定义信号示例,该示例将信号发送给工作线程.

I updated my code in the original post to include the UI file so you can run it, and I included an example of a custom signal in the GUI thread that sends a signal to the worker.

但是,在 for 循环完成之前,您不会看到 print 语句的输出,因为它会阻止 worker 处理信号,正如@three-pineapples 所述.

However you will not see the output of the print statement until the for loop has finished as it blocks the worker from processing signals, as @three-pineapples also stated.

所以,虽然这不是最好的例子,但希望如果有人在理解这个概念时遇到同样的问题,也许这会有所帮助.

So, although it's not the best example, hopefully if someone is having the same trouble understanding the concept, maybe this will help.

这篇关于PyQt5:如何向工作线程发送信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆