我编写了一个简单的客户端演示,客户端在服务器启动后需要重新连接到服务器,但是连接成功并出现错误?
server.py
from PyQt5.QtCore import *
from PyQt5.QtNetwork import *
from PyQt5.QtWidgets import *
class Server:
def __init__(self):
self.s = QTcpServer()
self.s.listen(QHostAddress.LocalHost, 9978)
self.s.newConnection.connect(self.on_new_connection)
self.cnt = 0
def on_new_connection(self):
self.c = self.s.nextPendingConnection()
self.c.readyRead.connect(self.on_read)
def on_read(self):
print('server:', self.c.readAll())
self.cnt += 1
self.c.write(bytes(str(self.cnt), encoding='utf-8'))
class ServerDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('server')
self.server = Server()
self.disBn = QPushButton('kick up', clicked=self.on_kick)
layout = QVBoxLayout()
layout.addWidget(self.disBn)
self.setLayout(layout)
def on_kick(self):
# simulate server kick up client
self.server.c.disconnectFromHost()
app = QApplication([])
s = ServerDemo()
s.resize(300, 200)
s.show()
app.exec()
client.py
from PyQt5.QtCore import *
from PyQt5.QtNetwork import *
from PyQt5.QtWidgets import *
import traceback
import time
class Client(QObject):
def __init__(self):
super().__init__()
self.sock = QTcpSocket(self)
self.sock.disconnected.connect(self.on_disc)
self.sock.readyRead.connect(self.on_data)
def on_data(self):
data = self.sock.readAll()
print('client:', data)
def on_disc(self):
print('reconnect')
self.sock.close()
self.sock.connectToHost(QHostAddress.LocalHost, 9978)
print('login success')
def sleep(self, v):
loop = QEventLoop()
QTimer.singleShot(v*1000, loop.quit)
loop.exec()
def do_work(self):
self.sock.connectToHost(QHostAddress.LocalHost, 9978)
for i in range(10000):
# print(self.sock.state())
self.sock.writeData(bytes(str(i), encoding='utf-8'))
self.sleep(1)
class ClientDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Client')
clientBn = QPushButton('start a thread', clicked=self.on_thread)
layout = QVBoxLayout()
layout.addWidget(clientBn)
self.setLayout(layout)
def on_thread(self):
self.client_thread = QThread()
self.worker = Client()
self.worker.moveToThread(self.client_thread)
self.client_thread.started.connect(self.worker.do_work)
self.client_thread.start()
app = QApplication([])
demo = ClientDemo()
demo.resize(300, 200)
demo.show()
app.exec()
我首先运行server.py,然后运行client.py,然后启动要运行的线程。 然后启动客户端,客户端尝试重新连接。但显示错误如下。
reconnect
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0x6cd4558), parent's thread is QThread(0x9583df0), current thread is QThread(0x131cfb8)
QObject::startTimer: Timers cannot be started from another thread
login success
QObject::killTimer: Timers cannot be stopped from another thread
QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
答案 0 :(得分:0)
我通过阅读很多文章成功解决了这个问题。
将self.sock = QTcpSocket(self)
更改为self.sock = QTcpSocket()
。
然后改变
def on_thread(self):
self.client_thread = QThread()
self.worker = Client()
self.worker.moveToThread(self.client_thread)
self.client_thread.started.connect(self.worker.do_work)
self.client_thread.start()
收件人
def on_thread(self):
self.client_thread = QThread()
self.worker = Client()
self.client_thread.started.connect(self.worker.do_work)
self.worker.moveToThread(self.client_thread)
self.client_thread.start()
备注:
QTcpSocket不能像在其他线程中那样使用,使用它有很多陷阱。
QTcpSocket很难跨越线程。