【问题标题】:Using QThread as receiver and sender使用 QThread 作为接收者和发送者
【发布时间】:2021-04-03 18:49:08
【问题描述】:

我怎样才能让工作线程接收我的数据、修改它并将其发回。在我的示例中,除了将数据发送到线程之外,我所有的东西都在运行。有没有办法通过信号来做到这一点?我可以使用 Queue 和 put/get 但是有没有解决方案可以从主线程获取信号到工作线程?

from PyQt5.QtCore import QTimer, QObject, QSize, pyqtSignal, QThread
from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction
import sys, queue
import time

class Test(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(800, 600)
        self.setMinimumSize(QSize(800, 600))

        toolbar = QToolBar("Toolbar")
        con = QAction("Connect", self)
        con.triggered.connect(self.connect)
        discon = QAction("Disconnect", self)
        discon.triggered.connect(self.disconnect)

        toolbar.addAction(con)
        toolbar.addAction(discon)
        self.addToolBar(toolbar)
        
        self.thread = None 
        self.counter = 0

    def connect(self):
        print("Connect")
        self.data = queue.Queue()
        self.thread = MyWorker(self.data)
        self.thread.back.connect(lambda count: self.DataFromWorker(count))
        self.thread.start()

        self.timer = QTimer()
        self.timer.timeout.connect(self.dataToWorker)
        self.timer.start(100)

    def disconnect(self):
        print("disconnect")
        if self.timer.isActive:
            self.timer.stop()

        if self.thread and self.thread.isRunning():
            self.thread.terminate()

    def dataToWorker(self):
        print("Send data to Worker")
        self.counter += 1
        self.data.put(self.counter)
        ###

    def DataFromWorker(self, count):
        print("Received data from Worker")
        print(count)


class MyWorker(QThread):
    back = pyqtSignal(int)

    def __init__(self, data):
        super().__init__()
        self.running = True
        self.data = data
        
    def run(self):
        while self.running:
            try:
                ###
                count = self.data.get(block=True, timeout=1)
                count += 10
                self.back.emit(count)
            except:
                pass
            


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Test()
    win.show()
    sys.exit( app.exec_() )

编辑:我编辑了上面的代码,因为示例不是很清楚。问题是,我怎样才能从主线程向工作线程发出信号。在示例中,我使用了队列,但有没有更好的方法来使用信号?

【问题讨论】:

  • self.thread.back.connect(lambda count: self.DataFromWorker(count)) 改为self.thread.back.connect(self.DataFromWorke)
  • emit 会将值转移到self.DataFromWorkecount
  • @dudulu 我不知道这对我有什么帮助,因为 self.DataFromWorker 已经在工作了。问题是如何将数据发送到我的工作线程?

标签: python multithreading pyqt qthread


【解决方案1】:

因为我的英文不好,也不是很理解问题,按照你的指示,你想把值发给Qthread,对吧?

class Test(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(800, 600)
        self.setMinimumSize(QSize(800, 600))

        toolbar = QToolBar("Toolbar")
        con = QAction("Connect", self)
        con.triggered.connect(self.connect)
        discon = QAction("Disconnect", self)
        discon.triggered.connect(self.disconnect)

        toolbar.addAction(con)
        toolbar.addAction(discon)
        self.addToolBar(toolbar)
        self.data = list()
        self.thread = None
        self.counter = 0

    def connect(self):
        print("Connect")
        self.thread = MyWorker(self.data)
        self.thread.back.connect(self.DataFromWorker)
        self.thread.start()

        self.timer = QTimer()
        self.timer.timeout.connect(self.dataToWorker)
        self.timer.start(100)

    def disconnect(self):
        print("disconnect")
        if self.timer.isActive:
            self.timer.stop()

        if self.thread and self.thread.isRunning():
            self.thread.terminate()

    def dataToWorker(self):
        print("Send data to Worker")
        self.counter += 5
        self.data.append(self.counter)
        ###

    def DataFromWorker(self, count):
        print("Received data from Worker")
        print(count)


class MyWorker(QThread):
    back = pyqtSignal(int)

    def __init__(self, data):
        super().__init__()
        self.running = True
        self.data = data

    def run(self):
        while self.running:
            try:
                ###
                count = self.data.pop(0)
                count += 10
                print(count)
                self.back.emit(count)
                time.sleep(1)
            except:
                pass

你可以用Queue,不知道有没有信号方法,根据你对Queue的使用,我会这样做。

【讨论】:

  • 我编辑了代码和问题。我希望它更清楚
  • 您可以使用QueueListDict。我通常使用ListDict 发送值。没用过信号传输方式。
  • 可以用Queue,不知道有没有信号的方法,我身边用Qt的人做的。
  • 如果我想在不同进程下共享数据,我只使用队列。
  • 但是当我使用列表时,我不再保存线程或者我错了吗?对于我的示例,这无关紧要,但总体而言,我搜索了一个线程保存解决方案
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
相关资源
最近更新 更多