Reputation: 85
I'm trying to have a button where if it is clicked it will insert a new button. I cant get the bind to return the new button.
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.uix.button import Button
class app(App):
def build(self):
layout = FloatLayout()
button1 =Button(text="test",pos=(385,450),size_hint=(.1,.1))
button1.bind(on_release=self.btn2)
layout.add_widget(button1)
return layout
def btn2(self, event):
print "worked"
layout = FloatLayout()
btn3 = Button(text="worked",size=(.1,.1),pos=(380,400))
layout.add_widget(btn3)
return layout
app().run()
Upvotes: 1
Views: 990
Reputation: 12199
You are creating another instance of FloatLayout
in the btn2
event with layout = FloatLayout()
, however that instance isn't anywhere else, but in the btn2
method - i.e. you added a Button
to FloatLayout
, but that layout isn't visible and after the function ends it's highly possible that even doesn't exist, because it's garbage-collected by Python.
You can either use partial
to pass the already existing instance of FloatLayout
(where your previous Button
is) like this if you need only one layout:
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from functools import partial
class app(App):
def build(self):
layout = FloatLayout()
button1 =Button(text="test",pos=(385,450),size_hint=(.1,.1))
button1.bind(on_release=partial(self.btn2, layout))
layout.add_widget(button1)
return layout
def btn2(self, layout, *args):
print "worked"
btn3 = Button(text="worked",size=(.1,.1),pos=(380,400))
layout.add_widget(btn3)
app().run()
Or you can use the instance that's passed to method arguments from the event (the instance of a widget that dispatched the event):
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
class app(App):
def build(self):
layout = FloatLayout()
button1 =Button(text="test",pos=(385,450),size_hint=(.1,.1))
button1.bind(on_release=self.btn2)
layout.add_widget(button1)
return layout
def btn2(self, button):
layout = button.parent # parent of the button is the "layout" from build()
btn3 = Button(text="worked",size=(.1,.1),pos=(380,400))
layout.add_widget(btn3)
app().run()
In both cases you only need to find the right instance to work with, not create another one that's not even used. Also return layout
isn't necessary if you don't expect on_release
to work with the layout
variable (which it won't).
Upvotes: 1