How to write an infinite loop for receiving UDP data?

浪尽此生 提交于 2021-01-27 21:14:52

问题


I'm trying to make an app that receives UDP data and shows the data in a list view using python (PyQt5). When I start the receiver, the app gets stuck and does not respond. How can I fix this? See code below.

import sys
import os
import socket
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class udpReceiverApp():
     app = QApplication (sys.argv)
     x = 1
     ip = "192.168.1.4"
     port =515
     server_start = True
     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     sock.bind((ip,port))

     def __init__(self):
         self.w = QWidget()
         self.lbl = QLabel ("udp receiver",self.w)
         self.btn = QPushButton ("click me",self.w)
         self.lst = QListWidget(self.w)
         self.lst.resize(200,100)

         self.lbl.move(10, 90)
         self.btn.move(50, 50)
         self.lst.move(10, 90)

         self.btn.clicked.connect(self.startReceiver)

         self.w.setGeometry(300, 300, 300, 200)
         self.w.setWindowTitle("udp receive")
         self.w.show()
         sys.exit(udpReceiverApp.app.exec_())

     def addLstItem(self):
         self.lst.insertItem(0,"item"+str(udpReceiverApp.x) )
         udpReceiverApp.x +=1

     def startReceiver(self):

         while udpReceiverApp.server_start:
               data, addr = self.sock.recvfrom(1024)
               self.lst.insertItem(0,data)

udpReceiverApp()

回答1:


You should not have an infinite loop in the main thread since it locks the Qt event loop, instead you should execute it in another thread and send the information through signals

import sys
import os
import socket
from PyQt5 import QtCore, QtWidgets

class UDPWorker(QtCore.QObject):
    dataChanged = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(UDPWorker, self).__init__(parent)
        self.server_start = False

    @QtCore.pyqtSlot()
    def start(self):
        self.server_start = True
        ip = "192.168.1.4"
        port = 515
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((ip,port))
        self.process()

    def process(self):
        while self.server_start:
            data, addr = self.sock.recvfrom(1024)
            self.dataChanged.emit(str(data))

class UDPWidget(QtWidgets.QWidget):
    started = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(UDPWidget, self).__init__(parent)
        btn = QtWidgets.QPushButton("Click Me")
        btn.clicked.connect(self.started)
        self.lst = QtWidgets.QListWidget()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(QtWidgets.QLabel("udp receiver"))
        lay.addWidget(btn)
        lay.addWidget(self.lst)

        self.setWindowTitle("udp receive")

    @QtCore.pyqtSlot(str)
    def addItem(self, text):
        self.lst.insertItem(0, text)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = UDPWidget()
    worker = UDPWorker()
    thread = QtCore.QThread()
    thread.start()
    worker.moveToThread(thread)
    w.started.connect(worker.start)
    worker.dataChanged.connect(w.addItem)
    w.show()
    sys.exit(app.exec_())


来源:https://stackoverflow.com/questions/55193145/how-to-write-an-infinite-loop-for-receiving-udp-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!