代码之家  ›  专栏  ›  技术社区  ›  Scott Melvin

无法在Kivy中引用小部件id

  •  0
  • Scott Melvin  · 技术社区  · 6 年前

    对于Kivy来说非常陌生,并且尝试动态添加小部件,但是尽管我遵循了所有的示例,我还是无法让我的小部件正常工作。

    我的kv文件是。。。

    ScreenManager:
        MainScreen:
        LoginScreen:
    
    <MainScreen>:
       name: 'MainScreen'
       id: ms
    
       BoxLayout:
            id: rc_display
            orientation: "vertical"
            padding: 10
            spacing: 10
    
            Label:
                id: ms_label1
                text: 'Oh Hell Yeah'
    
    <LoginScreen>:
        name: 'LoginScreen'
        id: ls
    
        Button:
            on_release: app.root.current
            text: 'Click to Login'
            font_size: 20
    

    我的python代码是。。。

    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.lang import Builder
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.button import Button
    import requests
    
    class MainScreen(Screen):
    
       def on_pre_enter(self, *args):
    
            show_view = self.ids.rc_display # error here
            show_view.clear_widgets()
            buttons = BoxLayout(orientation = 'vertical')
            pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
            for show in pr.json():
                buttons.add_widget(Button(text = show['show_title']))
    
            show_view.add_widgets(buttons)    
    
    class LoginScreen(Screen):
        pass
    
    class ScreenManagement(ScreenManager):
        pass
    
    class StagePlanningApp(App):
        def build(self):
    
            sm = Builder.load_file('StagePlanning.kv')
            # sm.add_widget(MainScreen())
            # sm.add_widget(LoginScreen())
            return sm
    
    sp_app = StagePlanningApp()
    sp_app.run()
    

    当我运行以上命令时,我得到以下错误。。。

    File "*pathtoFile*/StagePlanning.py", line 12, in on_pre_enter
     show_view = self.ids.rc_display
    File "kivy\properties.pyx", line 839, in kivy.properties.ObservableDict.__getattr__ (kivy\properties.c:12654)
    AttributeError: 'super' object has no attribute '__getattr__'
    

    如果我将这些小部件直接添加到屏幕对象中,它们会显示出来,但会相互重叠。只有当我尝试引用id时,我才会出错。

    我甚至已经将ID列表打印到控制台上,它们如预期的那样存在。

    1 回复  |  直到 6 年前
        1
  •  0
  •   eyllanesc Yonghwan Shin    6 年前

    问题是由于 on_pre_enter 事件在添加 BoxLayout 所以它不存在,一个可能的解决方案是使用 Clock :

    class MainScreen(Screen):
        def __init__(self, *args, **kwargs):
            Screen.__init__(self, *args, **kwargs)
            Clock.schedule_once(self.finished_init)
    
        def finished_init(self, *args):
            show_view = self.ids.rc_display # error here
            show_view.clear_widgets()
            buttons = BoxLayout(orientation = 'vertical')
            pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
            for show in pr.json():
                buttons.add_widget(Button(text = show['show_title']))
    
            show_view.add_widget(buttons) 
    

    另一个选项是在BoxLayout构造函数中定义它:

    *.py公司

    class MainBoxLayout(BoxLayout):
        def __init__(self, *args, **kwargs):
            BoxLayout.__init__(self, *args, **kwargs)
            self.clear_widgets()
            buttons = BoxLayout(orientation = 'vertical')
            pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
            for show in pr.json():
                buttons.add_widget(Button(text = show['show_title']))
            self.add_widget(buttons) 
    

    *.千伏

    ScreenManager:
        MainScreen:
        LoginScreen:
    
    <MainScreen>:
        name: 'MainScreen'
        id: ms
    
        MainBoxLayout:
            id: rc_display
            orientation: "vertical"
            padding: 10
            spacing: 10
    
    <LoginScreen>:
        name: 'LoginScreen'
        id: ls
    
        Button:
            on_release: app.root.current
            text: 'Click to Login'
            font_size: 20