简体   繁体   中英

Error on adding buttons dynamically in Kivy

To make my life a little easier I'm creating a dashboard on which I can operate things for multiple clients. Per client I have a folder with configuration files per client to dynamically build the rest of the page.

I'm now stuck with the first step, which is creating a button for every client I have.

   File "gui.py", line 25, in on_enter
     self.ids.clients.add_widget(clientbutton)
   File "kivy/properties.pyx", line 863, in kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'

gui.py:

import kivy
import os
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.clock import Clock

import subprocess

class ClientListWindow(Screen):   

    def on_enter(self, *args):
        dirs = next(os.walk('clients'))[1]

        for dir in dirs:
            print(dir)
            clientbutton = Button(text=dir)
            # clientbutton.bind(on_pressed=lambda *args: self.pressed('cltbtn', dir, *args))
            self.ids.clients.add_widget(clientbutton)

    def pressed(self, instance, *args):
        print("test")


class ClientGrid(Screen):  
    pass

class WindowManager(ScreenManager):
    pass

kv = Builder.load_file("gui.kv")
sm = WindowManager()

class GuiApp(App):
    def build(self):
        return kv

if __name__ == "__main__":
    GuiApp().run()

gui.kv

WindowManager:
    ClientListWindow:
    ClientGrid:

<ClientListWindow>:
    name: "clientlist"

    GridLayout:
        cols:2
        size: root.width, root.height

        GridLayout:
            cols:1

            Label:
                text: "Clients:"
                size_hint: 1, 0.1

            GridLayout:
                id: clients
                cols:2
                size_hint: 1, 0.9


<ClientGrid>:
    name: "client"
    

When I add print(self.ids) it looks like there are no ids found. When are these filled?

The documentation does not clearly define when the ids become available, but f you change your method definition from:

def on_enter(self, *args):

to

def on_kv_post(self, base_widget):

it will work. The on_kv_post() method gets called after the kv rules have been applied. This also has the advantage that the on_kv_post() method will only be called once, while the on_enter() method would get called every time the ClientListWindow gets displayed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM