Python PyQt5和Asyncio

Python PyQt5和Asyncio,python,pyqt,pyqt5,python-asyncio,coroutine,Python,Pyqt,Pyqt5,Python Asyncio,Coroutine,是否可以保持UDP服务器作为异步函数运行以接收数据,然后将其传递给(PyQt5)小部件,该小部件也作为异步函数运行 其思想是,当进入服务器的数据被更新时,它也会更新小部件 我已经有了一个简单的UDP服务器和一个(PyQt5)小部件,它们独立地工作得很好,但我正在努力将它们结合起来,使它们都异步运行并交换数据(服务器将数据传输到小部件) [更新] 下面是我正在试用的小部件 import sys from PyQt5 import QtWidgets, QtCore, QtGui from PyQt

是否可以保持UDP服务器作为异步函数运行以接收数据,然后将其传递给(PyQt5)小部件,该小部件也作为异步函数运行

其思想是,当进入服务器的数据被更新时,它也会更新小部件

我已经有了一个简单的UDP服务器和一个(PyQt5)小部件,它们独立地工作得很好,但我正在努力将它们结合起来,使它们都异步运行并交换数据(服务器将数据传输到小部件)

[更新]

下面是我正在试用的小部件

import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow
import asyncio


class Speedometer(QMainWindow):

    angleChanged = QtCore.pyqtSignal(float)

    def __init__(self, parent = None):

        QtWidgets.QWidget.__init__(self, parent)

        self._angle = 0.0

        self._margins = 20

        self._pointText = {0: "40", 30: "50", 60: "60", 90: "70", 120: "80",
                           150:"" , 180: "", 210: "",
                          240: "0", 270: "10", 300: "20", 330: "30", 360: ""}
    def paintEvent(self, event):

        painter = QtGui.QPainter()
        painter.begin(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        painter.fillRect(event.rect(), self.palette().brush(QtGui.QPalette.Window))
        self.drawMarkings(painter)
        self.drawNeedle(painter)

        painter.end()

    def drawMarkings(self, painter):

        painter.save()
        painter.translate(self.width()/2, self.height()/2)
        scale = min((self.width() - self._margins)/120.0,
                    (self.height() - self._margins)/60.0)
        painter.scale(scale, scale)

        font = QtGui.QFont(self.font())
        font.setPixelSize(10)
        metrics = QtGui.QFontMetricsF(font)

        painter.setFont(font)
        painter.setPen(self.palette().color(QtGui.QPalette.Shadow))

        i = 0

        while i < 360:

                if i % 30 == 0 and (i <150 or i > 210):
                    painter.drawLine(0, -40, 0, -50)
                    painter.drawText(-metrics.width(self._pointText[i])/2.0, -52,
                                     self._pointText[i])
                elif i <135 or i > 225:
                    painter.drawLine(0, -45, 0, -50)

                painter.rotate(15)
                i += 15

        painter.restore()

    def drawNeedle(self, painter):

        painter.save()
        painter.translate(self.width()/2, self.height()/1.5)
        painter.rotate(self._angle)
        scale = min((self.width() - self._margins)/120.0,
                    (self.height() - self._margins)/120.0)
        painter.scale(scale, scale) 

        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(self.palette().brush(QtGui.QPalette.Shadow))

        painter.drawPolygon(
            QtGui.QPolygon([QtCore.QPoint(-10, 0), QtCore.QPoint(0, -45), QtCore.QPoint(10, 0),
                      QtCore.QPoint(0, 5), QtCore.QPoint(-10, 0)])
            )

        painter.setBrush(self.palette().brush(QtGui.QPalette.Highlight))

        painter.drawPolygon(
            QtGui.QPolygon([QtCore.QPoint(-5, -25), QtCore.QPoint(0, -45), QtCore.QPoint(5, -25),
                      QtCore.QPoint(0, -30), QtCore.QPoint(-5, -25)])
            )

        painter.restore()

    def sizeHint(self):

        return QtCore.QSize(150, 150)

    def angle(self):
        return self._angle

#    @pyqtSlot(float)
    def setAngle(self, angle):

        if angle != self._angle:
            self._angle = angle
            self.angleChanged.emit(angle)
            self.update()

    angle = QtCore.pyqtProperty(float, angle, setAngle)

    @staticmethod
    def mainLoopSpd():
      while True:
            app = QApplication(sys.argv)

            window = QtWidgets.QWidget()
            spd = Speedometer()
            spinBox = QtWidgets.QSpinBox()
            #spd.setAngle(100)
            spinBox.setRange(0, 359)
            spinBox.valueChanged.connect(spd.setAngle)

            layout = QtWidgets.QVBoxLayout()
            layout.addWidget(spd)
            layout.addWidget(spinBox)
            window.setLayout(layout)

            window.show()
            app.exec_()
            #await asyncio.sleep(1)

            sys.exit(app.exec_())
下面是调用这两个函数的主要函数

from speedometer import Speedometer
import asyncio
from pyServer import UDPserver

class mainApp:
    #vel = 0
    def __init__(self):
        self.velo = 0
        self.queue= asyncio.Queue(0)

    async def server(self):

        while True:

            self.velo= UDPserver.mainLoopUDPserver()
            print("THIS IS VELO{}",self.velo)
            #await self.queue.put(self.velo)

            #vel= await self.queue.get()
            #return vel
            #print("ASSDASDSADSD{}",vel)

            await asyncio.sleep(0)
            #print("HI, vel Received={}",self.veloc)
        #return velo

    async def widget(self):
        while True:
            #vel =  await self.queue.get()
            #print("Hola xDDDDDDD", vel)
            print(">>>>>>>>>>>>>>>NextIteration>>>>>>>>>>>>>>")
            await Speedometer.mainLoopSpd()
            await asyncio.sleep(0)


loop= asyncio.get_event_loop()
mApp= mainApp()

loop.create_task(mApp.server())
loop.create_task(mApp.widget())
loop.run_forever()
因此,当我运行它时,它会监听服务器,一旦我开始通过UDP发送数据,它就会接收第一条数据并打开运行正常的小部件,但它会使服务器停止,它不再接收任何数据

正如您在评论中所看到的,我也一直在使用异步IO队列,但实际上我什么都没有

我的理想场景是服务器接收数据并将其传递给小部件,以便使用传入的数据进行更新,但目前我只希望它们都独立工作


谢谢

应该清楚,您的UDP服务器不是异步运行的

asyncio的逻辑是所有东西都使用eventloop作为基础,默认情况下Qt不支持它,因此必须使用(
python-m pip install qasync
)和(
python-m pip install asyncqt
)等库

考虑到上述情况,解决方案是:

车速表.py

从PyQt5导入QtCore、QtGui、qtwidget
类速度计(qtwidts.QWidget):
角度更改=QtCore.pyqtSignal(浮动)
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
自转角=0.0
自选页边距=20
self.\u pointText={
0: "40",
30: "50",
60: "60",
90: "70",
120: "80",
150: "",
180: "",
210: "",
240: "0",
270: "10",
300: "20",
330: "30",
360: "",
}
def paintEvent(自身,事件):
painter=QtGui.QPainter(自)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.fillRect(event.rect(),self.palete().brush(QtGui.QPalette.Window))
自绘制标记(油漆工)
自吸针(油漆工)
def图纸标记(自身、油漆工):
保存
painter.translate(self.width()/2,self.height()/2)
刻度=最小值(
(self.width()-self._边距)/120.0,
(自高度()-self._边距)/60.0,
)
画师:比例(比例,比例)
font=QtGui.QFont(self.font())
font.setPixelSize(10)
metrics=QtGui.QFontMetricsF(字体)
painter.setFont(字体)
painter.setPen(self.palete().color(QtGui.qpalete.Shadow))
i=0
而我<360:
如果i%30==0且(i<150或i>210):
油漆工.抽绳(0,-40,0,-50)
绘画文本(
-metrics.width(self.\u pointText[i])/2.0,-52,self.\u pointText[i]
)
如果i<135或i>225:
油漆工.抽绳(0,-45,0,-50)
油漆工。旋转(15)
i+=15
恢复
def抽油针(自身、油漆工):
保存
painter.translate(self.width()/2,self.height()/1.5)
油漆工。旋转(自身角度)
刻度=最小值(
(self.width()-self._边距)/120.0,
(自高度()-self._边距)/120.0,
)
画师:比例(比例,比例)
painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(self.palete().brush(QtGui.qpalete.Shadow))
画师(
QtGui.QPolygon(
[
QtCore.QPoint(-10,0),
QtCore.QPoint(0,-45),
QtCore.QPoint(10,0),
QtCore.QPoint(0,5),
QtCore.QPoint(-10,0),
]
)
)
painter.setBrush(self.palete().brush(QtGui.qpalete.Highlight))
画师(
QtGui.QPolygon(
[
QtCore.QPoint(-5,-25),
QtCore.QPoint(0,-45),
QtCore.QPoint(5,-25),
QtCore.QPoint(0,-30),
QtCore.QPoint(-5,-25),
]
)
)
恢复
def sizeHint(自身):
返回QtCore.QSize(150150)
def角度(自):
返回自转角
@QtCore.pyqtSlot(浮动)
def设置角度(自身、角度):
如果角度!=自转角:
自身角度=角度
self.angleChanged.emit(角度)
self.update()
角度=QtCore.pyqtProperty(浮点、角度、设置角度)
如果名称=“\uuuuu main\uuuuuuuu”:
导入系统
导入异步
从asyncqt导入QEventLoop
app=qtwidts.QApplication(sys.argv)
循环=QEventLoop(应用程序)
asyncio.set\u event\u循环(循环)
带循环:
w=速度表()
w、 角度=10
w、 show()
loop.run_forever()
server.py

导入异步IO
从PyQt5导入QtCore
类UDPserver(QtCore.QObject):
dataChanged=QtCore.pyqtSignal(浮点,浮点,浮点,浮点)
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
自身运输=无
自身计数器消息=0
@财产
def传输(自):
返回自我运输
def连接(自行、运输):
自我运输=运输
接收到def数据报(自身、数据、地址):
自身计数器信息+=1
打印(“收到的Mssg数量:{}”。格式(自我计数器消息))
message=data.decode()
东乌德
from speedometer import Speedometer
import asyncio
from pyServer import UDPserver

class mainApp:
    #vel = 0
    def __init__(self):
        self.velo = 0
        self.queue= asyncio.Queue(0)

    async def server(self):

        while True:

            self.velo= UDPserver.mainLoopUDPserver()
            print("THIS IS VELO{}",self.velo)
            #await self.queue.put(self.velo)

            #vel= await self.queue.get()
            #return vel
            #print("ASSDASDSADSD{}",vel)

            await asyncio.sleep(0)
            #print("HI, vel Received={}",self.veloc)
        #return velo

    async def widget(self):
        while True:
            #vel =  await self.queue.get()
            #print("Hola xDDDDDDD", vel)
            print(">>>>>>>>>>>>>>>NextIteration>>>>>>>>>>>>>>")
            await Speedometer.mainLoopSpd()
            await asyncio.sleep(0)


loop= asyncio.get_event_loop()
mApp= mainApp()

loop.create_task(mApp.server())
loop.create_task(mApp.widget())
loop.run_forever()