【问题标题】:How to send packet data to dialog?如何将数据包数据发送到对话框?
【发布时间】:2018-07-14 23:26:21
【问题描述】:

我通过 pyqt5 制作了一些接收到的 tcp 数据包对话框。
此代码是加载对话框,在 qthread 中调用接收 tcp 数据包。
我想将数据包数据发送到对话框。
如何发送?

这是我的代码。

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import socketserver


class MyTCPHandler(socketserver.StreamRequestHandler):
    def handle(self):
        try:
            data = self.rfile.read(28)
            # how to send packet data to dialog?

        except Exception as e:
            print('MyTCPHandler.handle exception error: ', e)


class TestThread(QThread):
    HOST, PORT = '192.168.0.100', 8484

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

    def receive_packet(self):
        socketserver.TCPServer.allow_reuse_address = True
        server = socketserver.TCPServer((self.HOST, self.PORT), MyTCPHandler)
        server.serve_forever()

    def run(self):
        print('run thread')
        self.receive_packet()


class TestGUI(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.btn1 = QPushButton("start thread", self)
        self.textbox1 = QLineEdit(self)
        vertBox = QVBoxLayout()
        vertBox.addWidget(self.btn1)
        vertBox.addWidget(self.textbox1)
        self.setLayout(vertBox)
        self.setGeometry(700, 500, 300, 100)
        self.btn1.clicked.connect(self.threadStart)
        self.show()

        self.th = TestThread(self)


    @pyqtSlot()
    def threadStart(self):
        self.th.start()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = TestGUI()
    app.exec_()

【问题讨论】:

    标签: python sockets pyqt pyqt5 qthread


    【解决方案1】:

    发送线程信息可以使用QMetaObject.invokeMethod(),所以需要通过GUI,在这种情况下我们利用QThread的父级是GUI。

    您可以设置一个新属性以将 GUI 传递给处理程序,并从处理程序通过 self.server 访问该属性。

    最后,我们实现了一个接收信息的槽。

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    import socketserver
    
    
    class MyTCPHandler(socketserver.StreamRequestHandler):
        def handle(self):
            try:
                data = self.rfile.read(28)
                QMetaObject.invokeMethod(self.server.w, "setData",
                    Qt.QueuedConnection, Q_ARG(bytes, data))
    
            except Exception as e:
                print('MyTCPHandler.handle exception error: ', e)
    
    
    class TestThread(QThread):
        HOST, PORT = '192.168.0.102', 8000
        def __init__(self, parent=None):
            super().__init__(parent)
    
        def receive_packet(self):
            socketserver.TCPServer.allow_reuse_address = True
            server = socketserver.TCPServer((self.HOST, self.PORT), MyTCPHandler)
            server.w = self.parent()
            server.serve_forever()
    
        def run(self):
            print('run thread')
            self.receive_packet()
    
    
    class TestGUI(QDialog):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.btn1 = QPushButton("start thread", self)
            self.textbox1 = QLineEdit(self)
            vertBox = QVBoxLayout()
            vertBox.addWidget(self.btn1)
            vertBox.addWidget(self.textbox1)
            self.setLayout(vertBox)
            self.setGeometry(700, 500, 300, 100)
            self.btn1.clicked.connect(self.threadStart)
            self.show()
    
            self.th = TestThread(self)
    
        @pyqtSlot(bytes)
        def setData(self, data):
            print(data)
    
        @pyqtSlot()
        def threadStart(self):
            self.th.start()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        form = TestGUI()
        sys.exit(app.exec_())
    

    @Plus:有信号

    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    import socketserver
    
    
    class MyTCPHandler(socketserver.StreamRequestHandler):
        def handle(self):
            try:
                data = self.rfile.read(28)
                self.server.qthread.dataChanged.emit(data)
    
            except Exception as e:
                print('MyTCPHandler.handle exception error: ', e)
    
    
    class TestThread(QThread):
        HOST, PORT = '192.168.0.102', 8000
        dataChanged = pyqtSignal(bytes)
        def __init__(self, parent=None):
            super().__init__(parent)
    
        def receive_packet(self):
            socketserver.TCPServer.allow_reuse_address = True
            server = socketserver.TCPServer((self.HOST, self.PORT), MyTCPHandler)
            server.qthread = self
            server.serve_forever()
    
        def run(self):
            print('run thread')
            self.receive_packet()
    
    
    class TestGUI(QDialog):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.btn1 = QPushButton("start thread", self)
            self.textbox1 = QLineEdit(self)
            vertBox = QVBoxLayout()
            vertBox.addWidget(self.btn1)
            vertBox.addWidget(self.textbox1)
            self.setLayout(vertBox)
            self.setGeometry(700, 500, 300, 100)
            self.btn1.clicked.connect(self.threadStart)
            self.show()
    
            self.th = TestThread(self)
            self.th.dataChanged.connect(self.setData)
    
        @pyqtSlot(bytes)
        def setData(self, data):
            print(data)
    
        @pyqtSlot()
        def threadStart(self):
            self.th.start()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        form = TestGUI()
        sys.exit(app.exec_())
    

    【讨论】:

    • 谢谢!埃兰斯克。您修改后的代码有效!谢谢!!
    • @SUNGHOLEE 如果我的回答对你有帮助,别忘了标记为正确,如果你不知道怎么做,请查看tour
    • 现在,我通过您的向导了解了QMetaObject.invokeMethod()。没有别的办法?
    • 你也可以使用信号。
    • 可以在class MyTCPHandler发信号吗?
    猜你喜欢
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2017-04-27
    • 1970-01-01
    相关资源
    最近更新 更多