-2

I'm using socketserver and pyqt5 to make a udpserver, like this:

class UdpServer(socketserver.BaseRequestHandler):
    signal_msg=pyqtSignal(str)
    def handle(self):
        data =self.request[0]
        signal_msg.emit(data.decode('utf-8'))

then I use a qtbutton to start this class,like this:

udpserver=socketserver.ThreadingUDPServer(('127.0.0.1',8081),UdpServer)
def udpthr(): 
    udpserver.serve_forever()
threading.Thread(target=udpthr,args=()).start()

the question is ,how to use the 'signal_msg' in pyqt5? Since "UdpServer" doesn't have a instance, I can't access the variable in the class.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

1

The signals only make sense in the QObjects since they are used to obtain information about the type of information that you want to transmit and implement all the internal logic. Considering this then you must create a QObject with a signal that has the signature of the information you send, then pass that object as an attribute of the server so that it is used in the handle method.

import sys
import socketserver
import threading

from PyQt5 import QtCore, QtGui, QtWidgets


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


class UDPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = str(self.request[0], "ascii")
        self.server.bridge.dataChanged.emit(data)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        self.label.setFont(QtGui.QFont("Arial", 20))

        self.setCentralWidget(self.label)
        self.resize(640, 480)

    @QtCore.pyqtSlot(str)
    def update_text(self, text):
        self.label.setText(text)


def main():
    app = QtWidgets.QApplication(sys.argv)

    bridge = Bridge()

    w = MainWindow()
    w.show()

    HOST, PORT = "127.0.0.1", 8081
    server = socketserver.ThreadingUDPServer((HOST, PORT), UDPHandler)
    ip, port = server.server_address
    print(ip, port)
    server.bridge = bridge

    bridge.dataChanged.connect(w.update_text)

    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()

    ret = app.exec_()

    server.server_close()

    sys.exit(ret)


if __name__ == "__main__":
    main()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241