Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
585 views
in Technique[技术] by (71.8m points)

python - How to write an infinite loop for receiving UDP data?

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()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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_())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...