PyQt5继承QTcpServer/QTcpSocket出现NoneType属性错误求助
问题描述
基于PyQt5的QTcpSocket和QTcpServer实现自定义TCP套接字与服务器时,重写QTcpServer.incomingConnection方法返回自定义MyNewSocket实例,调用nextPendingConnection能拿到预期实例,但访问其属性/方法时,先输出正确结果随后抛出AttributeError: 'NoneType' object has no attribute 'anyAttribute'。
以下是复现代码:
tcpmodule.py
from PyQt5.QtNetwork import QTcpSocket, QTcpServer class MyNewSocket(QTcpSocket): """自定义套接字类""" pass class MyNewServer(QTcpServer): def incomingConnection(self, handle): """重写方法返回自定义套接字""" socket = MyNewSocket(self) socket.setSocketDescriptor(handle) self.addPendingConnection(socket) self.newConnection.emit() # 手动触发信号
server.py
from tcpmodule import MyNewServer from PyQt5.QtWidgets import QApplication, QMainWindow from PyQt5.QtNetwork import QHostAddress app = QApplication([]) win = QMainWindow() server = MyNewServer(win) server.listen(QHostAddress.SpecialAddress.LocalHost, 9999) def newConnection(): socket = server.nextPendingConnection() print("Acces any Attribute ", socket.connected) print("Socket is ", socket, " Socket Type is", type(socket)) server.newConnection.connect(newConnection) win.show() app.exec()
client.py
#!/usr/bin/env python3 from tcpmodule import MyNewSocket from PyQt5.QtWidgets import QApplication, QMainWindow from PyQt5.QtNetwork import QHostAddress app = QApplication([]) win = QMainWindow() socket = MyNewSocket(win) socket.connectToHost(QHostAddress.SpecialAddress.LocalHost, 9999) def connected(): socket.write(b"Hello, World!") socket.connected.connect(connected) win.show() app.exec()
运行后输出:
Acces any Attribute <bound PYQT_SIGNAL connected of MyNewSocket object at 0x7f4be28597e0> Socket is <tcpmodule.MyNewSocket object at 0x7f4be28597e0> Socket Type is <class 'tcpmodule.MyNewSocket'> Traceback (most recent call last): File "./server.py", line 13, in newConnection print("Acces any Attribute ", socket.connected) AttributeError: 'NoneType' object has no attribute 'connected'
原因分析
问题出在MyNewServer.incomingConnection方法里手动调用了self.newConnection.emit()。实际上,当你调用self.addPendingConnection(socket)时,QTcpServer内部会自动触发newConnection信号。这就导致newConnection槽函数被执行两次:
- 第一次:
nextPendingConnection从队列中取出你添加的MyNewSocket实例,正常输出属性信息; - 第二次:队列已经为空,
nextPendingConnection返回None,此时访问None.connected就会抛出AttributeError。
解决方案
删除incomingConnection方法中手动触发信号的代码,让QTcpServer自动处理信号触发:
修改后的MyNewServer类:
class MyNewServer(QTcpServer): def incomingConnection(self, handle): socket = MyNewSocket(self) socket.setSocketDescriptor(handle) self.addPendingConnection(socket) # 移除 self.newConnection.emit()
这样newConnection信号只会被触发一次,槽函数中nextPendingConnection只会返回有效的MyNewSocket实例,不会出现None的情况。
内容的提问来源于stack exchange,提问作者Torilla
相关产品推荐
相关产品推荐

