You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 16:45:46