Question: Is it possible to keep a UDP server running as an asynchronous function receiving data and then passing it to an (PyQt5) widget which is also running as an asynchronous function?? The idea is that when the data coming into the server is updated, it also updates the widget. I have got a simple UDP server and a (PyQt5) widget already which are working fine independently but I am struggling trying to combine them and keep them both running asynchronously and exchanging data(Server transmitting data to widget) [UPDATE] Below is a widget that I am trying out 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_())  Below is an implementation of a UDP socket end which also is printing the values in the console 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)  and below is the main function which is calling them both 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()  So, when I run it, it listens to the server and once I start sending data over UDP, it receives the first piece of data and open the widget which is runs just fine but it makes the server to stop, it does not receive any data anymore. As you can see in the comments, I have also been playing around with Asyncio queues, but I haven't got anything really.  My ideal scenario would be the server receiving the data and passing it to the widget so it gets updated with the incoming data but for now I just want them both working independently. Thanks

Answer: It should be clear that your UDP server does not run asynchronously. The logic of asyncio is that everything uses an eventloop as a base, and by default Qt does not support it, so you must use libraries such as qasync(python -m pip install qasync) and asyncqt(python -m pip install asyncqt) Considering the above, the solution is: speedometer.py from PyQt5 import QtCore, QtGui, QtWidgets class Speedometer(QtWidgets.QWidget): angleChanged = QtCore.pyqtSignal(float) def __init__(self, parent=None): super().__init__(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(self) painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.fillRect(event.rect(), self.palette().brush(QtGui.QPalette.Window)) self.drawMarkings(painter) self.drawNeedle(painter) 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 @QtCore.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) if __name__ == "__main__": import sys import asyncio from asyncqt import QEventLoop app = QtWidgets.QApplication(sys.argv) loop = QEventLoop(app) asyncio.set_event_loop(loop) with loop: w = Speedometer() w.angle = 10 w.show() loop.run_forever()  server.py import asyncio from PyQt5 import QtCore class UDPserver(QtCore.QObject): dataChanged = QtCore.pyqtSignal(float, float, float, float) def __init__(self, parent=None): super().__init__(parent) self._transport = None self._counter_message = 0 @property def transport(self): return self._transport def connection_made(self, transport): self._transport = transport def datagram_received(self, data, addr): self._counter_message += 1 print("#Num of Mssg Received: {}".format(self._counter_message)) message = data.decode() east_coord_str, north_coord_str, veh_speed_str, ag_yaw_str, *_ = message.split( "/" ) try: east_coord = float(east_coord_str) north_coord = float(north_coord_str) veh_speed = float(veh_speed_str) ag_yaw = float(ag_yaw_str) self.dataChanged.emit(east_coord, north_coord, veh_speed, ag_yaw) except ValueError as e: print(e)  main.py import sys import asyncio from PyQt5 import QtCore, QtWidgets from asyncqt import QEventLoop from speedometer import Speedometer from server import UDPserver class Widget(QtWidgets.QWidget): def __init__(self, parent=None): super().__init__(parent) self.spd = Speedometer() self.spinBox = QtWidgets.QSpinBox() self.spinBox.setRange(0, 359) self.spinBox.valueChanged.connect(lambda value: self.spd.setAngle(value)) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.spd) layout.addWidget(self.spinBox) @QtCore.pyqtSlot(float, float, float, float) def set_data(self, east_coord, north_coord, veh_speed, ag_yaw): print(east_coord, north_coord, veh_speed, ag_yaw) self.spd.setAngle(veh_speed) async def create_server(loop): return await loop.create_datagram_endpoint( lambda: UDPserver(), local_addr=("127.0.0.1", 20002) ) def main(): app = QtWidgets.QApplication(sys.argv) loop = QEventLoop(app) asyncio.set_event_loop(loop) w = Widget() w.resize(640, 480) w.show() with loop: _, protocol = loop.run_until_complete(create_server(loop)) protocol.dataChanged.connect(w.set_data) loop.run_forever() if __name__ == "__main__": main()