如何在 kivy 中的 for 循环中创建按钮后为其提供 id

问题描述 投票:0回答:0

所以对于一个学校项目,我们正在制作游戏,我们选择制作 Connway 的生活游戏。

我要寻求帮助的问题是以下一个:

我在我的 kv 文件中用 for 循环制作了一个 10*10 的 ToggleButton 网格,但为了让游戏正常运行,我需要给它们一个 ID(它们具有相同或不同的 ID 并不重要)。我尝试了很多东西,但每次我尝试给他们一个 ID 而不是数字时我都会遇到同样的问题,它说 name 未定义,如果他们在这里是一个数字,我不能稍后再打电话给他们是代码:

py.:

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.graphics import Canvas
from kivy.graphics import Rectangle
from kivy.lang import Builder

from kivy.properties import ObjectProperty
from kivy.properties import ListProperty

from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.screenmanager import NoTransition 
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget

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

global a
a = "play"

        
class Jeu(Screen):     
    def start(self):
        Clock.schedule_interval(the_callback,0.1)
    def stop(self):
        Clock.unschedule(the_callback)
    def test(self):
        print(self.size)
        

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

class SettingsScreen(Screen):
    sound=SoundLoader.load('oui.wav')
    def fullscreen(self):
        name = self.ids.fullscreen.text
        if  Window.fullscreen == True:
            self.ids.fullscreen.text = 'Fullscreen off'
            Window.fullscreen = False
        else:
            self.ids.fullscreen.text = 'Fullscreen on'
            Window.fullscreen = True
    
    def music(self):
        sound=SoundLoader.load('oui.wav')
        name = self.ids.music.text
        global a
        if a == "play":
            self.ids.music.text = 'Music off'
            a= "stop"
             
        else:
            self.ids.music.text = 'Music on'
            a= "play"

class PloytestApp(App):
    def build(self):
        # Create the screen manager
        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

sound=SoundLoader.load('oui.wav')
def my_callback(dt):
    if a=="stop":
        sound.stop()
    elif a =="play":
        sound.play()
event = Clock.schedule_interval(my_callback, 1 / 30.)

def the_callback(dt):
    print("aaaaa")
    
if __name__ == '__main__':
    PloytestApp().run()
    App.stop(exit())


和我的kv:

#: import Window kivy.core.window.Window 
#:  import Clock kivy.clock


    
<MenuScreen>:
    GridLayout:
        cols: 1
        FloatLayout:
            Image:
                id: gif
                source: 'test.zip' 
                allow_stretch: True
                keep_aspect: False
                size: 1200, 800
                size_hint: None, None
                pos_hint:{"center_x": .4, "center_y": .05}
                anim_loop: 0
            Label:
                pos: self.parent.pos
                size: self.parent.size
                text:"Connway's game of life"
                font_size: 60
                color: 0.5, 0.8, 1, 1
                
        FloatLayout:
            cols: 1
            Button:
                text: 'Play'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .9}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:
                    root.manager.current = 'jeu'
            Button:
                text:  'How to Play'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .7}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:
                    root.manager.current = 'rules'
            Button:
                text: 'Goto settings'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .5}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release: 
                    root.manager.current = 'settings'
            Button:
                text: 'Quit'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .3}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release: 
                    app.stop() 

<Jeu>:  
    FloatLayout:
        RecycleView:
            btn: "btn"
            data: [{'background_color': (1,1,1,1),'id': btn} for x in range(10 * 10)]
            viewclass: 'ToggleButton'
            RecycleGridLayout:
                rows: 10
                cols: 10
                size_hint: 1, 1
                default_size_hint: 1, 1
                
    GridLayout:
        size_hint: 1, 0.1
        cols:4
        ToggleButton:
            id:start
            text: 'Start simulation'
            on_state:
                if self.state == 'normal':\
                print("aa")
                root.start()
                if self.state == 'normal':\
                root.stop()
        Button:
            id:next
            text: 'Next Generation'
        Button:
            id:clear
            text: 'Clear'
            on_press:
                start.state ='normal' if start.state == 'down' else 'normal'
            on_release:
                Viewclass.state ='normal'
        Button:
            text:"Back to menu"
            on_press:
                start.state ='normal' if start.state == 'down' else 'normal'
            on_release: 
                root.manager.current = 'menu'
        
<RuleScreen>:
    FloatLayout:
        cols:1
        Image:
            source: 'rules.jpg'
        FloatLayout:
            cols: 2
            Button:
                text: 'Setting'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .8, "center_y": .3}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:
                    root.manager.current = 'settings'
            Button:
                text: 'Back to menu'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .8, "center_y": .2}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:
                    root.manager.current = 'menu'

<SettingsScreen>:
    GridLayout:
        cols: 1
        FloatLayout:
            Image:
                id: gif
                source: 'test.zip' 
                allow_stretch: True
                keep_aspect: False
                size: 1200, 800
                size_hint: None, None
                pos_hint:{"center_x": .4, "center_y": .05}
                anim_loop: 0
            Label:
                pos: self.parent.pos
                size: self.parent.size
                text:"Settings"
                font_size: 60
                color: 0.5, 0.8, 1, 1
        FloatLayout:
            cols: 1
            Button:
                id: fullscreen
                text: "Fullscreen off"
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .7}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:
                    root.fullscreen()
            Button:
                id: music
                text: "Music on"
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .5}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:
                    root.music()
            Button:
                text: 'Back to menu'
                size: 100, 50
                size_hint: None, None
                pos_hint: {"center_x": .5, "center_y": .3}
                background_normal: ''
                background_color:(89/255, 100/255, 210/255, 1)
                on_release:                
                    root.manager.current = 'menu'

我在运行程序时遇到的错误是:

*     67:        RecycleView:
     68:            btn: "btn"
>>   69:            data: [{'background_color': (1,1,1,1),'id': btn} for x in range(10 * 10)]
     70:            viewclass: 'ToggleButton'
     71:            RecycleGridLayout:
...
NameError: name 'btn' is not defined
  File "C:\Users\mitch\AppData\Roaming\Python\Python310\site-packages\kivy\lang\builder.py", line 240, in create_handler
    return eval(value, idmap), bound_list
  File "C:\Users\mitch\Desktop\thonny code\test bench\kivy prog1\kivy_avec_kvfiles\polytana test avec kivy\ploytest.kv", line 69, in <module>
    data: [{'background_color': (1,1,1,1),'id': btn} for x in range(10 * 10)]
  File "C:\Users\mitch\Desktop\thonny code\test bench\kivy prog1\kivy_avec_kvfiles\polytana test avec kivy\ploytest.kv", line 69, in <listcomp>
    data: [{'background_color': (1,1,1,1),'id': btn} for x in range(10 * 10)]

  File "C:\Users\mitch\AppData\Roaming\Python\Python310\site-packages\kivy\lang\builder.py", line 694, in _apply_rule
    value, bound = create_handler(
  File "C:\Users\mitch\AppData\Roaming\Python\Python310\site-packages\kivy\lang\builder.py", line 243, in create_handler
    raise BuilderException(rule.ctx, rule.line,*

我几乎尝试了我所知道的一切来解决它,但我无法解决它。 我试图将 id 放在 python 文件的列表中,这样我就可以为列表做得更好,并在按钮之间添加简单的交互,但是当数字不可调用时,id 也是同样的问题。

如有解决方案,万分感谢 抱歉英语水平很差,这不是我的母语。

python kivy kivy-language thonny
© www.soinside.com 2019 - 2024. All rights reserved.