将消息发送到其他QThread

时间:2014-03-03 16:17:48

标签: python multithreading pyside signals-slots qthread

我正在试图弄清楚如何实现让我的主线程产生一个新线程的概念,该线程在传递消息时同时处理数据。

从我的想法到目前为止,最简单的方法是:

from PySide.QtCore import QCoreApplication, QObject, Signal, QThread, QTimer


class Foo(QObject):
    do_foo = Signal(str)

    def __init__(self, parent=None):
        super(Foo, self).__init__(parent)
        self.do_foo.connect(self._do_foo)

    def foo(self, string):
        self.do_foo.emit(string)

    def _do_foo(self, string):
        # Process string
        print "Process thread:", self.thread().currentThreadId()


class App(QCoreApplication):
    def run(self):
        print "Main thread:", self.thread().currentThreadId()
        thread = QThread()
        foo = Foo()
        foo.moveToThread(thread)
        thread.start()

        # Obviously the following should be done with the event-loop
        # or at doing processing of events.
        running = True
        while running:
            try:
                string = raw_input()
                foo.foo(string)
            except EOFError:
                running = False

        thread.exit()
        thread.wait()
        self.exit()

if __name__ == '__main__':
    import sys
    app = App(sys.argv)
    QTimer.singleShot(0, app.run)
    sys.exit(app.exec_())

但如果这样做的话,我就看不出Slot的使用方式了。

1 个答案:

答案 0 :(得分:1)

或者您可以使用“Provider-Consumer”设计模式。这个怎么运作?那么你必须实现一个queue spwaned线程将从此queue获取数据,而主线程将向queue提供新数据。

enter image description here

当队列为空时,您生成的线程会阻塞。这样你甚至可以处理多个线程中的数据,而且你不必担心两个线程试图读取相同的数据。

以下是消费者线程的一些seudo代码。

class MyThread:
    def __init__(self, queue):
        self.queue = queue
        self.event = Event()    # I generally use threading.Event for stopping threads. You don't need it here.

   def run():
       while not self.event.isSet():
          data = self.queue.get()   # This stop the thread until new data be available.
          do_something_with_data(data)

然后在main thread

import Queue
queue = Queue.Queue()
mthread = MyThread(queue)
mthread.start()

# And now you can send data to threads by:
queue.put(data)