"""When clicking on the button generated by the *.KV file, the buttons are generated in a grid (2). When clicking on the button of the "Create" class, the buttons are generated superimposed. How do I solve the overlay buttons problem?"""
test.py
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
class Test(App):
def build(self):
return Window()
class Window(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cols = 2
self.col_force_default = True
self.col_default_width = 200
self.row_force_default = True
self.row_default_height = 40
self.add_widget((Button(text="Create",
on_release=Window.addWidget)))
def addWidget(self):
count = 0
while count < 10:
count = count 1
self.add_widget(Button(text=str(count)))
Test().run()
test.kv
<Window>:
BoxLayout:
Button:
on_release:root.addWidget()
CodePudding user response:
In your python code the line:
on_release=Window.addWidget)))
arranges for Window.addWidget()
to be called when the Button
is released. When an on_release
is specified, the Button
that was release is passed as an argument to the specified method. So, when the Button
is released, the actual call is executed as:
Window.addWidget(button_instance)
Now the addWidget()
method of your Window
class is an instance method, meaning that it expects the first argument passed to it is the self
(the instance of the Window
class). Since you are not calling it properly as an instance method, the passed in button_instance
is mistaken for the Window
class instance, and the created Buttons
are added to the button_instance
instead of the Window
instance.
You can fix this by correctly calling the addWidget()
method like this:
on_release=lambda button: self.addWidget())))
The lambda
is just to remove the added button_instance
argument.
A different fix is to add *args
to the addWidget()
, like this:
def addWidget(self, *args):
Then the on_release
line is simpler:
on_release=self.addWidget)))