结合ZMQ事件循环和QT/Pyforms事件循环

2024-05-19 01:12:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试实现这两者,zmq和pyformsgui,它们都需要有自己的事件循环。任务是要有一个带有textfield的Pyforms GUI,它显示传入的zmq消息。 这是我正在努力工作的简化代码。在

import pyforms
from   pyforms          import BaseWidget
from   pyforms.controls import ControlTextArea
from   pyforms.controls import ControlButton
import threading
import zmq
from zmq.asyncio import Context
from zmq.eventloop.zmqstream import ZMQStream
from zmq.eventloop import ioloop


class SimpleExample1(BaseWidget):

    def __init__(self):
        super(SimpleExample1,self).__init__('Simple example 1')

        #Definition of the forms fields
        self._controltextarea     = ControlTextArea('textarea to show incoming zmq messages')
        self._button        = ControlButton('Press this button')

        def echo(msg):
            self._controltextarea.__add__(msg) #this should add a line in the Textbox with the message "msg"


        context = Context.instance()
        s = context.socket(zmq.PULL)
        s.connect('tcp://127.0.0.1:5014')
        stream = ZMQStream(s)
        stream.on_recv(echo)  #this calls the function echo from the zmq Ioloop when something is recived

#Execute the application
if __name__ == "__main__":
    #here is where I have tried a lot to make both loops work simultaniously, without success
    guiThread = threading.Thread(target=pyforms.start_app( SimpleExample1 ))
    zmqThread = threading.Thread(target=lambda: ioloop.IOLoop.current().start())
    zmqThread.setDaemon(True)
    guiThread.start()
    zmqThread.start()

这是ZMQ发送器。在

^{pr2}$

我看到了两种可能的解决方案。 首先,它可以像上面的代码那样使用线程。但我还没有找到启动两个事件循环的方法。要么一个语句阻塞了另一个语句,要么我在不使用lamda等语句时收到错误消息,要么就是它不起作用。-下面是我试图实现的一个引用,但没有成功,它描述了一个类似的任务:github maartenbreddels

第二个选项是将echo()的zmq函数调用添加到Pyforms的eventloop中(据我所知,它是基于QT的)。这可能是最优雅的,但我不知道如何实现或添加一些东西到GUI的事件循环中。在

两种解决方案我都试了很多次,但都没有成功。
我能找到的最有价值的信息是:

pyzmq readthedocs

zeromq org

pyforms readthedocs

我没有太多的经验,我试图理解一些东西,比如未来、承诺和协同程序,还有asyncio、python中的green等框架,但到目前为止还没有成功。一个简单的函数调用“echo”,只要收到一条消息,就是我想要的。在

有什么办法吗?我在做傻事吗?在


Tags: thefromimportechoself消息eventloop事件
2条回答

提前为一个模糊的答案道歉,但也许这可以作为一个潜在的起点。在

PyForms最终看起来是基于Qt的。Qt我认为可以使用一个socket(好吧,一个文件描述符)作为输入甚至源。ZeroMQ(至少是C版本)公开了一个文件描述符,当接收到ZMQ消息时,该描述符就可以读取了。所以在原则上,Qt可以使用这个文件描述符来调用一个回调函数来读取zmqsocket接收到的任何消息,并在Qt事件循环的线程上处理该消息(这可能还有其他好处!)。在

恐怕我不知道这些是否被PyZMQ和PyForms公开。在

谢谢你的意见。你的回答帮助我找到了解决问题的办法。在搜索了如何发出Qevent之后,我找到了下面的示例example并解决了问题。 最终代码如下:

import pyforms
from   pyforms          import BaseWidget
from   pyforms.controls import ControlTextArea
from   pyforms.controls import ControlButton
import threading
import zmq
from PyQt5 import QtCore

class ZeroMQ_Listener(QtCore.QObject):

    message = QtCore.pyqtSignal(str)

    def __init__(self):

        QtCore.QObject.__init__(self)

        # Socket to talk to server
        context = zmq.Context()
        self.socket = context.socket(zmq.PULL)
        self.socket.connect('tcp://127.0.0.1:5014')
        print('connected!')
        self.running = True

    def loop(self):
        while self.running:
            string = self.socket.recv_string()
            self.message.emit(string)


class SimpleExample1(BaseWidget):

    def __init__(self):
        super(SimpleExample1,self).__init__('Simple example 1')

        #Definition of the forms fields
        self._controltextarea     = ControlTextArea('textarea to show incoming zmq messages')
        self._button        = ControlButton('Press this button')

        message = QtCore.pyqtSignal(str)
        self.thread = QtCore.QThread()
        self.zeromq_listener = ZeroMQ_Listener()

        self.zeromq_listener.moveToThread(self.thread)

        self.thread.started.connect(self.zeromq_listener.loop)
        self.zeromq_listener.message.connect(self.signal_received)

        QtCore.QTimer.singleShot(0, self.thread.start)


    def signal_received(self, message):
        self._controltextarea.__add__(message)

#Execute the application
if __name__ == "__main__":
    guiThread = threading.Thread(target=pyforms.start_app( SimpleExample1 ))

    guiThread.start()

非常感谢并致以最诚挚的问候!!!在

相关问题 更多 >

    热门问题