【发布时间】:2018-08-15 14:43:51
【问题描述】:
我正在尝试同时实现 zmq 和 Pyforms GUI,它们都需要有自己的事件循环。任务是拥有一个带有文本字段的 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 发送者。
import zmq
import time
context = zmq.Context()
publisher = context.socket(zmq.PUSH)
publisher.bind('tcp://127.0.0.1:5014')
while True:
publisher.send_string('something')
#print('sended')
time.sleep(1)
我看到了 2 种可能的解决方案。 首先,它可以与上面代码中的线程一起工作。但是我还没有找到一种方法来启动两个事件循环。当我不使用 lamda 等时,一个语句会阻塞另一个语句,或者我收到错误消息。或者它只是不工作。 - 这是我尝试实现但没有成功的参考,描述了类似的任务:github maartenbreddels
第二种选择是将 echo() 的 zmq 函数调用添加到 Pyforms 的事件循环中(据我所知,它是基于 QT 的)。这可能是最优雅的,但我不知道如何实现或向 GUI 的事件循环添加一些东西。
我对这两种解决方案都进行了很多尝试,但均未成功。
我能找到的最有价值的信息在这里:
我没有太多经验,并试图理解诸如期货、承诺和协程之类的东西,以及诸如 asyncio 之类的框架,到目前为止,python 中的绿色还没有成功。一旦收到消息,一个简单的“echo”函数调用就是我正在寻找的。p>
任何想法如何使它工作?我在做傻事吗?
【问题讨论】:
标签: python event-handling zeromq pyforms