Python:如何将龙卷风read_message()的结果传递给QT5 UI元素



我有一个python qt5应用程序,该应用程序在另一个线程中启动龙卷风插座客户端。我想知道的是,每当我在Tornado的Websocket.read_message()中获得结果时,如何将该值传递给QT5 GUI标签。

这是Main.py,它在新线程中启动QT5 GUI应用程序和龙卷风Websocket。

import sys
import threading
from PyQt5.QtWidgets import QApplication
from app.ui.components import MainWindow
from app.client import Client
from config import SERVER_URL
def main():
    app = QApplication(sys.argv)
    form = MainWindow()
    form.show()
    sys.exit(app.exec_())
if __name__ == '__main__':
    client = Client("ws://{0}/socket".format(SERVER_URL), 5)
    thread = threading.Thread(target=lambda : client.ioloop.start())
    thread.setDaemon(True)
    thread.start()
    main()

这是client.py

from tornado import gen
from tornado.ioloop import IOLoop, PeriodicCallback
from tornado.websocket import websocket_connect
class Client(object):
    def __init__(self, url, timeout):
        self.url = url
        self.timeout = timeout
        self.ioloop = IOLoop.instance()
        self.ws = None
        self.connect()
        self.periodic_callback = PeriodicCallback(self.keep_alive, 20000, io_loop=self.ioloop)
    @gen.coroutine
    def connect(self):
        try:
            self.ws = yield websocket_connect(self.url)
            self.periodic_callback.start()
        except Exception as e:
            pass
        else:
            self.run()
    @gen.coroutine
    def run(self):
        while True:
            msg = yield self.ws.read_message()
            if msg is None:
                self.ws = None
                break
            print("Received: {0}".format(msg)) # HOW TO PASS msg to GUI LABEL WHENEVER IT RECEIVES A NEW VALUE
    def keep_alive(self):
        if self.ws is None:
            self.connect()
        else:
            self.ws.write_message("Hello from client")

龙卷风线程可以从原始线程中访问内存中的对象。因此,一个非常简单的解决方案是将QApplication或其他对象从QT应用程序传递到客户端对象。然后,当您收到消息时,您可以调用QT对象上的任何方法。

但是,很明显这将安全起作用。QT对象可能无法设计为从两个不同的线程访问。在不知道要使用类的情况下,您不应该假设它是 thread-safe 。因此,简单的解决方案可能意味着同时某些QT代码在主线程上运行,龙卷风线程调用了一些QT代码,该代码改变了QT对象的状态。另一个代码没想到会发生变化,因此您会崩溃或其他故障。

您可能会发现QT库旨在应对的。但是在任何情况下都是更好的方法-A 生产者 - 消费者队列

这意味着您有一个队列对象,该对象在线程之间共享。这可以是您已经使用的threading模块的threading.Queue。每次收到WebSocket时,您都会在队列上进行put。这可能是任何python对象 - 如果需要的话,只是消息字符串,或者如果需要的话,则可以进行一些自定义对象。

然后,在另一个线程上,您有一个循环,该循环仅从队列中读取,并在每次收到消息时调用QT。

编辑 - QT可能可以处理此

我对QT了解不多。但是,大多数窗口系统实际上都有自己的事件队列,在此处管理点击,按键按下等。如果在此事件队列上处理了QT更新某些内容,则可能意味着它们是线程安全的。这是因为您从龙卷风线程中调用的函数并不能直接更改GUI,而是在QT到达QT时只会在要处理的队列中添加一些东西。

我快速看一些关于QT的东西,看来这可能是QT的工作方式,您应该从龙卷风线程中找到它,而无需实现自己的队列。

相关内容

  • 没有找到相关文章

最新更新