1

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?

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.