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

Kivy开发Connect4游戏遇AttributeError:无法修改圆圈颜色

解决四子连珠游戏中Kivy点击按钮修改圆圈颜色的报错问题

报错原因分析

  • Canvas指令不能设置id:你在Kivy的Color绘图指令里添加了id: AA1,但id仅适用于Kivy的Widget组件(如Button、Label),Color属于Canvas绘图指令,不属于Widget范畴,因此通过self.ids.AA1访问会触发属性错误。
  • 变量访问逻辑错误:Python代码中x = x+1未通过self.x访问类属性,无法正确更新玩家回合计数器,会导致玩家切换逻辑失效。
  • 颜色修改方式错误:你试图直接修改Color指令的rgba值,但该指令的rgba已经绑定到root.colunA1类属性,正确的做法是直接修改这个绑定的属性来更新颜色。

修复后的代码

Python代码

from kivy.app import App 
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.properties import ListProperty  # 用ListProperty支持颜色属性的绑定更新

class Tela(Widget):
    x = 1

    # 玩家颜色,用ListProperty让Kivy监听属性变化
    player1 = ListProperty((1,0,0,1))
    player2 = ListProperty((0,0,1,1))

    # A列的颜色属性,绑定到Kivy中的Color指令
    colunA1 = ListProperty((1,1,1,1))
    A1 = 0  # 标记位置是否被占用
    colunA2 = ListProperty((1,1,1,1))
    A2 = 0
    colunA3 = ListProperty((1,1,1,1))
    A3 = 0
    colunA4 = ListProperty((1,1,1,1))
    A4 = 0
    colunA5 = ListProperty((1,1,1,1))
    A5 = 0
    colunA6 = ListProperty((1,1,1,1))
    A6 = 0

    def botaocolunA(self):
        if self.A1 == 0:
            # 根据回合切换玩家颜色
            if self.x % 2 == 0:
                self.colunA1 = self.player2
            else:
                self.colunA1 = self.player1
            self.A1 = 1  # 标记该位置已被占用
            self.x += 1  # 更新玩家回合
    
    # 其他列属性同理,后续可优化为列表存储减少重复代码
    colunB1 = ListProperty((1,1,1,1))
    colunC1 = ListProperty((1,1,1,1))
    colunD1 = ListProperty((1,1,1,1))
    colunE1 = ListProperty((1,1,1,1))
    colunF1 = ListProperty((1,1,1,1))
    colunG1 = ListProperty((1,1,1,1))

class AulaApp(App):
    def build(self):
        self.title = " Lig4 "
        Window.size = (670,500)
        return Tela()
    
AulaApp().run()

Kivy代码

<Tela>
    canvas:
        Color:  
            rgba: 0.1,0.1,0.1,1
        Rectangle:            
            pos: self.pos
            size: self.size
        Color:
            rgba: 1,0,0,1
        Rectangle:
            pos: (5,470)
            size: (100,40)
        Color:
            rgba: 0,0,1,1
        Rectangle:
            pos: (100,470)
            size: (100,40)
        Color:
            rgba: 0,0,0,1
        Rectangle:
            pos: (5,410)
            size: (195,60)
        Color:
            rgba: 0.6,0.6,0.6,1
        Rectangle:
            pos: (200, 5)
            size: (670,900)

        #Coluna A
        Color:
            rgba: root.colunA1  # 绑定到类属性,无需设置id
        Ellipse:
            pos: (210,5)
            size: (70,70)

        Color:
            rgba: root.colunA2
        Ellipse:
            pos: (210,80)
            size: (70,70)

        Color:
            rgba: root.colunA3
        Ellipse:
            pos: (210,155)
            size: (70,70)

        Color:
            rgba: root.colunA4
        Ellipse:
            pos: (210,230)
            size: (70,70)
        
        Color:
            rgba: root.colunA5
        Ellipse:
            pos: (210,305)
            size: (70,70)

        Color:
            rgba: root.colunA6
        Ellipse:
            pos: (210,380)
            size: (70,70)
        # Coluna B
        Color:
            rgba: root.colunB1
        Ellipse:
            pos: (290,5)
            size: (70,70)

        Color:
            rgba: root.colunB1
        Ellipse:
            pos: (290,80)
            size: (70,70)

        Color:
            rgba: root.colunB1
        Ellipse:
            pos: (290,155)
            size: (70,70)

        Color:
            rgba: root.colunB1
        Ellipse:
            pos: (290,230)
            size: (70,70)
        
        Color:
            rgba: root.colunB1
        Ellipse:
            pos: (290,305)
            size: (70,70)

        Color:
            rgba: root.colunB1
        Ellipse:
            pos: (290,380)
            size: (70,70)
        # Coluna C
        Color:
            rgba: root.colunC1
        Ellipse:
            pos: (370,5)
            size: (70,70)

        Color:
            rgba: root.colunC1
        Ellipse:
            pos: (370,80)
            size: (70,70)

        Color:
            rgba: root.colunC1
        Ellipse:
            pos: (370,155)
            size: (70,70)

        Color:
            rgba: root.colunC1
        Ellipse:
            pos: (370,230)
            size: (70,70)
        
        Color:
            rgba: root.colunC1
        Ellipse:
            pos: (370,305)
            size: (70,70)

        Color:
            rgba: root.colunC1
        Ellipse:
            pos: (370,380)
            size: (70,70)
        # Coluna D
        Color:
            rgba: root.colunD1
        Ellipse:
            pos: (450,5)
            size: (70,70)

        Color:
            rgba: root.colunD1
        Ellipse:
            pos: (450,80)
            size: (70,70)

        Color:
            rgba: root.colunD1
        Ellipse:
            pos: (450,155)
            size: (70,70)

        Color:
            rgba: root.colunD1
        Ellipse:
            pos: (450,230)
            size: (70,70)
        
        Color:
            rgba: root.colunD1
        Ellipse:
            pos: (450,305)
            size: (70,70)

        Color:
            rgba: root.colunD1
        Ellipse:
            pos: (450,380)
            size: (70,70)
        # Coluna E
        Color:
            rgba: root.colunE1
        Ellipse:
            pos: (530,5)
            size: (70,70)

        Color:
            rgba: root.colunE1
        Ellipse:
            pos: (530,80)
            size: (70,70)

        Color:
            rgba: root.colunE1
        Ellipse:
            pos: (530,155)
            size: (70,70)

        Color:
            rgba: root.colunE1
        Ellipse:
            pos: (530,230)
            size: (70,70)
        
        Color:
            rgba: root.colunE1
        Ellipse:
            pos: (530,305)
            size: (70,70)

        Color:
            rgba: root.colunE1
        Ellipse:
            pos: (530,380)
            size: (70,70)
        #Coluna F
        Color:
            rgba: root.colunF1
        Ellipse:
            pos: (610,5)
            size: (70,70)

        Color:
            rgba: root.colunF1
        Ellipse:
            pos: (610,80)
            size: (70,70)

        Color:
            rgba: root.colunF1
        Ellipse:
            pos: (610,155)
            size: (70,70)

        Color:
            rgba: root.colunF1
        Ellipse:
            pos: (610,230)
            size: (70,70)
        
        Color:
            rgba: root.colunF1
        Ellipse:
            pos: (610,305)
            size: (70,70)

        Color:
            rgba: root.colunF1
        Ellipse:
            pos: (610,380)
            size: (70,70)
        #Coluna G
        Color:
            rgba: root.colunG1
        Ellipse:
            pos: (690,5)
            size: (70,70)

        Color:
            rgba: root.colunG1
        Ellipse:
            pos: (690,80)
            size: (70,70)

        Color:
            rgba: root.colunG1
        Ellipse:
            pos: (690,155)
            size: (70,70)

        Color:
            rgba: root.colunG1
        Ellipse:
            pos: (690,230)
            size: (70,70)
        
        Color:
            rgba: root.colunG1
        Ellipse:
            pos: (690,305)
            size: (70,70)

        Color:
            rgba: root.colunG1
        Ellipse:
            pos: (690,380)
            size: (70,70)
        
    # Botao Coluna A
    Button: 
        canvas:
            Color:
                rgba: (1,1,0,1)
        pos: (210,460)
        size: (70,30)
        on_release: root.botaocolunA()
          
    Label:
        text: "Player 1"
        pos: (5,470)
        size: (100,40)
    Label:
        text: "Player 2"
        pos: (100,470)
        size: (100,40)
    Label:
        text: "Placar:"
        pos: (50, 440)
        size: (100, 40)
    Label:
        text: "X"
        pos: (50,410)
        size: (100,40)
    Label:
        text: "0"
        pos: (30, 410)
        size: (100,40)
        id: placarvermelho

    Label:
        text: "0"
        pos: (70,410)
        size:(100,40)
        id: placarazul
    
    Button:
        text: "Jogar"
        pos: 10,70
        size: 100,50

额外优化建议

  • 将所有列的颜色和状态存储为二维列表(如colunas = [[(1,1,1,1) for _ in range(6)] for _ in range(7)]),避免重复定义大量单个变量,简化后续的落子逻辑编写。
  • 实现自动下落逻辑:点击列时,自动找到该列最下方的空位置进行着色,而非仅修改第一个位置。

内容的提问来源于stack exchange,提问作者Vinicius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:42:03