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

Kivy中按钮触发服务器连接后self.sock为None引发AttributeError问题

问题描述

希望通过按钮触发服务器连接,而非应用启动时自动连接。在TitleWindow的__init__方法中初始化MySocket客户端类时功能正常,但改为通过按钮调用函数初始化后,调用get_data和send_data时self.sock变为None,触发如下错误:

self.sock.send_data(msg)
AttributeError: 'NoneType' object has no attribute 'send_data'
错误原因

核心问题是实例不匹配:

  • 在main.py中手动创建了control = TitleWindow(),但这个实例和Kivy的WindowManager自动创建的TitleWindow实例是两个完全独立的对象。
  • 按钮触发的是WindowManager管理的TitleWindow实例的connection方法,初始化的是该实例的self.sock;但MainWindow和ConnectionWindow中调用的是手动创建的control实例的方法,这个control的self.sock从未被初始化,始终为None。
解决方案

1. 删除无效的手动实例

删除main.py中的control = TitleWindow()这一行,避免混淆实例。

2. 通过ScreenManager获取真实实例

在需要调用TitleWindow方法的地方,通过self.manager.get_screen("title")获取WindowManager管理的真实TitleWindow实例:

  • 修改ConnectionWindow的reconnect方法:
def reconnect(self):
    try:
        title_screen = self.manager.get_screen("title")
        title_screen.connection()
    except Exception as e:
        print(str(e))
        print("No Connection")
  • 修改MainWindow的data_call方法(注意不要覆盖send_data方法):
def data_call(self):
    title_screen = self.manager.get_screen("title")
    title_screen.send_data(str(self.seat))

3. 修正send_data函数的冗余逻辑

原函数中的while True循环无意义(直接break),且未处理msg为None的情况,修改如下:

def send_data(self, msg=None):
    # 处理空消息,避免编码错误
    if msg is None:
        msg = ""
    self.sock.send_data(msg)

4. 补充缺失的模块导入

原代码使用了sleep但未导入,在main.py顶部添加:

from time import sleep

5. 修正kv文件语法错误

ConnectionWindow定义缺少冒号,修改为:

<ConnectionWindow>:
    name : "connect"
    # 其余内容不变
关键修正后的代码片段

修正后的ConnectionWindow:

class ConnectionWindow(Screen):
    def reconnect(self):
        try:
            title_screen = self.manager.get_screen("title")
            title_screen.connection()
        except Exception as e:
            print(str(e))
            print("No Connection")

    def top(self):
        self.manager.current = "title"
        self.manager.transition.direction = "up"

修正后的MainWindow:

class MainWindow(Screen):
    def __init__(self, **kwargs):
        super(MainWindow, self).__init__(**kwargs)
        self.seat = 0

    def data_call(self):
        title_screen = self.manager.get_screen("title")
        title_screen.send_data(str(self.seat))

修正后的TitleWindow的send_data:

def send_data(self, msg=None):
    if msg is None:
        msg = ""
    self.sock.send_data(msg)

内容的提问来源于stack exchange,提问作者アフィク

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:54:52