Issue
I made some received tcp packet dialog by pyqt5.
This code are load dialog, call receive tcp packet in qthread.
I want to send packet data to dialog.
How to send?
It's my code.
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_()
Solution
To send the information of a thread you can use QMetaObject.invokeMethod()
, so it is necessary to pass the GUI, and in this case we take advantage that the parent of the QThread is the GUI.
You can set a new property to pass the GUI to the handler, and from the handler access that property through self.server.
Finally, we implemented a slot that receives the information.
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: with signals
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_())
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.