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

如何在Kivy的Jeu屏幕中创建10×10 ToggleButton网格?

康威生命游戏:添加10×10 ToggleButton网格解决方案

核心问题分析

  • 不能将Jeu类从Screen改为GridLayout——ScreenManager仅接受Screen类型组件,修改后会导致程序无法启动。
  • 动态生成ToggleButton网格需在Jeu的初始化流程中完成,确保组件正确挂载到Screen布局内。

修改后的Python代码

import numpy as np
from collections import namedtuple

from kivy.app import App
from kivy.clock import Clock
from kivy.core.audio import SoundLoader
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import ObjectProperty, ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.screenmanager import NoTransition, ScreenManager, Screen

field = namedtuple('field', ['rows', 'cols'])
FIELD = field(30, 60)

# 全局变量控制音乐状态
a = "play"

class Jeu(Screen):
    def __init__(self, **kwargs):
        super(Jeu, self).__init__(**kwargs)
        # 创建主布局:垂直排列网格和控制按钮
        main_layout = GridLayout(cols=1)
        
        # 10×10的ToggleButton网格
        self.cell_grid = GridLayout(cols=10, size_hint=(1, 0.8))
        self.cells = []
        for i in range(10):
            row = []
            for j in range(10):
                btn = ToggleButton()
                btn.bind(on_press=self.on_cell_toggle)
                row.append(btn)
                self.cell_grid.add_widget(btn)
            self.cells.append(row)
        
        # 控制按钮布局
        control_layout = GridLayout(cols=4, size_hint=(1, 0.2))
        self.start_btn = ToggleButton(id='start', text='开始模拟')
        self.start_btn.bind(on_state=self.on_start_toggle)
        control_layout.add_widget(self.start_btn)
        control_layout.add_widget(Button(id='next', text='下一代', on_press=self.next_generation))
        control_layout.add_widget(Button(id='clear', text='清空', on_press=self.clear_grid))
        control_layout.add_widget(Button(text="返回菜单", on_release=self.go_back_to_menu))
        
        # 将布局添加到Screen
        main_layout.add_widget(self.cell_grid)
        main_layout.add_widget(control_layout)
        self.add_widget(main_layout)
    
    def on_cell_toggle(self, instance):
        # 处理单元格点击事件,可在这里更新生命游戏状态
        pass
    
    def on_start_toggle(self, instance, value):
        if value == 'down':
            Clock.schedule_interval(self.update_simulation, 0.1)
        else:
            Clock.unschedule(self.update_simulation)
    
    def update_simulation(self, dt):
        # 生命游戏迭代逻辑,这里先保留打印测试
        print("模拟中...")
    
    def next_generation(self, instance):
        # 手动触发下一代逻辑
        pass
    
    def clear_grid(self, instance):
        # 清空所有ToggleButton状态
        for row in self.cells:
            for btn in row:
                btn.state = 'normal'
        self.start_btn.state = 'normal'
    
    def go_back_to_menu(self, instance):
        self.start_btn.state = 'normal'
        self.manager.current = 'menu'

class MenuScreen(Screen):     
    pass
            
class RuleScreen (Screen):
    pass

class SettingsScreen(Screen):
    def __init__(self, **kwargs):
        super(SettingsScreen, self).__init__(**kwargs)
        self.sound = SoundLoader.load('oui.wav')
    
    def fullscreen(self):
        if Window.fullscreen:
            self.ids.fullscreen.text = '关闭全屏'
            Window.fullscreen = False
        else:
            self.ids.fullscreen.text = '开启全屏'
            Window.fullscreen = True
    
    def music(self):
        global a
        if a == "play":
            self.ids.music.text = '关闭音乐'
            a = "stop"
            self.sound.stop()
        else:
            self.ids.music.text = '开启音乐'
            a = "play"
            self.sound.play()

class PloytestApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(MenuScreen(name='menu'))
        sm.add_widget(Jeu(name='jeu'))
        sm.add_widget(RuleScreen(name='rules'))
        sm.add_widget(SettingsScreen(name='settings'))
        sm.transition = NoTransition()
        return sm

if __name__ == '__main__':
    PloytestApp().run()

修改后的kv文件

#: import Window kivy.core.window.Window 

<MenuScreen>:
    GridLayout:
        cols: 1
        Image:
            id: gif
            source: 'test.zip' 
            allow_stretch: True
            keep_aspect: False
            anim_loop: 0
            Label:
                pos: self.parent.pos
                size: self.parent.size
                text:"康威生命游戏"
                font_size: 60
                color: 0.5, 0.8, 1, 1
                
        GridLayout:
            cols: 1
            Button:
                text: '开始游戏'
                on_release:
                    root.manager.current = 'jeu'
            Button:
                text: '游戏规则'
                on_release:
                    root.manager.current = 'rules'
            Button:
                text: '设置'
                on_release: 
                    root.manager.current = 'settings'
            Button:
                text: '退出'
                on_release: app.stop() 

<RuleScreen>:
    GridLayout:
        cols:1
        Image:
            source: 'rules.jpg'
        GridLayout:
            cols: 2
            Button:
                text: '设置'
                on_release:
                    root.manager.current = 'settings'
            Button:
                text: '返回菜单'
                on_release:
                    root.manager.current = 'menu'

<SettingsScreen>:
    GridLayout:
        cols: 1
        size: root.width - 100, root.height -100
        Button:
            id: fullscreen
            text: "关闭全屏"
            on_release:
                root.fullscreen()
        Button:
            id: music
            text: "开启音乐"
            on_release:
                root.music()
        Button:
            text: '返回菜单'
            on_release:                
                root.manager.current = 'menu'

关键修改说明

  1. 保留Jeu的Screen继承:确保组件能正常加入ScreenManager,解决程序无法启动的问题。
  2. 动态生成ToggleButton网格:在Jeu的__init__方法中创建10×10网格,循环添加按钮并存储引用,方便后续操作单元格状态。
  3. 修正控制按钮逻辑:
    • 修复"开始模拟"按钮的状态切换逻辑,按下启动定时器,松开停止。
    • 整合"清空"和返回菜单按钮的状态重置逻辑,确保返回时停止模拟。
  4. 优化音乐控制:将音乐播放/停止逻辑整合到SettingsScreen中,移除全局回调,代码更简洁。
  5. 修正kv文件错误:移除无效注释,调整布局缩进,将界面文本翻译为中文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:07:04