I have on MacOs this Python3 script:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
class Grid(GridLayout):
cols=2
def doet(self):
self.ids.grid_id.add_widget(Button())
class app(App):
def build(self):
self.grid=Grid()
return Builder.load_file('lab.kv')
app().run()
And this kv file (lab.kv):
BoxLayout:
Button:
text:'Doet'
on_press:app.grid.doet()
Grid:
id:grid_id
I try to add a widget to the grid from python class by clicking a button, but it doesn't work. I get this error message:
AttributeError: 'super' object has no attribute '__getattr__'
P.s. I tried this too:
self.add_widget(Button())
I don't get error messages, but nothing happens.
A couple problems with your code:
doet()
method tries to reference ids
of the Grid
class, but the Grid
class has no ids
. The ids
defined in your kv
are in the BoxLayout
class. See the documentation.on_press:app.grid.doet()
in your kv
calls the doet()
method of the grid
attribute of your app
class. That grid
attribute is defined the the build()
method (self.grid=Grid()
) and is not included in your app
display, so running its methods will have no effect on what you see.The fix is to eliminate unused widgets, and correctly access the widgets that are actually in your App
. Here is a modified version of your code that does this:
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
class Grid(GridLayout):
cols=2
def doet(self):
self.add_widget(Button()) # add new Button to the Grid
class app(App):
def build(self):
# self.grid=Grid()
return Builder.load_file('lab.kv')
app().run()
lab.kv:
BoxLayout:
Button:
text:'Doet'
on_press: grid_id.doet()
Grid:
id:grid_id
The grid_id.doet()
in the kv
uses the defined id
to access the Grid
that is actually in the App
.