能否将一个UDP服务器保持运行作为异步函数接收数据,然后将其传递给同时作为异步函数运行的(PyQt5)小部件?
思路是当服务器接收到的数据更新时,它也会更新小部件。
我已经有一个简单的UDP服务器和(PyQt5)小部件,它们独立地工作良好,但我正在努力将它们结合起来并使它们都异步运行并交换数据(服务器传输数据到小部件)。
[更新]
下面是我正在尝试的小部件。
下方是一个UDP套接字端口的实现,同时也会在控制台打印出值。
当我运行它时,它会监听服务器。一旦我开始通过UDP发送数据,它就接收第一个数据片段并打开小部件,这很好,但这会使服务器停止接收任何数据。
正如您在注释中看到的,我也一直在尝试使用Asyncio队列,但我什么都没有得到。
我的理想情况是服务器接收数据并将其传递给小部件,以便其随着传入数据进行更新,但目前我只想让它们独立工作。
谢谢
思路是当服务器接收到的数据更新时,它也会更新小部件。
我已经有一个简单的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_())
下方是一个UDP套接字端口的实现,同时也会在控制台打印出值。
import socket
class UDPserver:
def __init__(self, parent= None):
self.localIP = "127.0.0.1"
self.localPort = 20002
self.bufferSize = 1024
self.UDPServerSocket = socket.socket(family= socket.AF_INET, type=socket.SOCK_DGRAM) # Create a socket object
self.UDPServerSocket.bind((self.localIP, self.localPort))
print("UDP server up and listening")
self.counter= 1
@staticmethod
def mainLoopUDPserver():
serv= UDPserver()
#while(True):
bytesAddressPair = serv.UDPServerSocket.recvfrom(serv.bufferSize) # Receive data from the socket
message = bytesAddressPair[0] # The output of the recvfrom() function is a 2-element array
# First element is the message
address = bytesAddressPair[1] # Second element is the address of the sender
newMsg= "{}".format(message)
serv.counter=serv.counter+1
NumMssgReceived = "#Num of Mssg Received:{}".format(serv.counter)
newMsg= newMsg.replace("'","")
newMsg= newMsg.replace("b","")
newMsg= newMsg.split("/")
eastCoord= float(newMsg[0])
northCoord= float(newMsg[1])
vehSpeed= float(newMsg[2])
agYaw= float(newMsg[3])
eastCoordStr="East Coordinate:{}".format(newMsg[0])
northCoordStr="North Coordinate:{}".format(newMsg[1])
vehSpeedStr= "Vehicle Speed:{}".format(newMsg[2])
agYawStr="Yaw Angle:{}".format(newMsg[3])
print(NumMssgReceived)
print(vehSpeedStr)
以下是调用两个函数的主功能
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发送数据,它就接收第一个数据片段并打开小部件,这很好,但这会使服务器停止接收任何数据。
正如您在注释中看到的,我也一直在尝试使用Asyncio队列,但我什么都没有得到。
我的理想情况是服务器接收数据并将其传递给小部件,以便其随着传入数据进行更新,但目前我只想让它们独立工作。
谢谢