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
相关产品推荐
相关产品推荐

