Nesting Widgets In Kivy
Solution 1:
The reason you get a blank screen is that your app's build()
method does not return anything. Whatever it returns would be the root widget, but even though you make some widgets you don't return one so nothing is displayed.
If you fix this, you can run the app again but you'll immediately get an error something like MyApp has no attribute rect
. This is because your root widget is immediately sized and positioned to fill the window, which (as per your root.bind
line) triggers MyApp._update_rect
. However, this method try to modify MyApp.rect.pos...but the app doesn't have a self.rect! You presumably intended to bind to root._update_rect
, not the app's method. (Edit: I bound to root._update_rect
instead and now at least the red background and green circle do appear.)
Edit: And as a side note, this would be a lot easier using the kv language, which could automatically take care of a lot of the widget creation, rectangle binding etc.
I don't have time to fix it all right now, but perhaps these two problems can help you fix the overall flow. I'll try to post a more complete answer later if nobody else has.
Here's an updated MyApp, as per the comments.
classMyApp(App):
title = 'My App'defbuild(self):
root = RootWidget()
root.bind(
size=root._update_rect,
pos=root._update_rect)
Solution 2:
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle, Ellipse
classMyApp(App):
title = 'My App'defbuild(self):
root = RootWidget()
root.bind(
size=root._update_rect,
pos=root._update_rect)
return root
classRootWidget(FloatLayout):
def__init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
with self.canvas.before:
Color(1, 0, 0, 1) # This RED does not display.
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="some junk!") # This label does not display.
mybackground = Background()
self.add_widget(mybackground)
def_update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
classBackground(Widget):
def__init__(self, **kwargs):
super(Background, self).__init__(**kwargs)
with self.canvas.before:
Color(1, 1, 1, 1) # This WHITE does not display
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="More stuff!") # This label does not display.
myholder = Holder()
self.add_widget(myholder)
def_update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
classHolder(Widget):
def__init__(self, **kwargs):
super(Holder, self).__init__(**kwargs)
with self.canvas.before:
Color(0.25, 0.25, 0.25, 1) # This GRAY does not display
self.rect = Rectangle(
size=self.size,
pos=self.pos,
text="More stuff!") # This does not display.
c1 = Circley(label="Label 1") # I see I'd need to do some size/pos math here to center
c2 = Circley(label="Label 2") # but since everything isn't working, I've tabled this.
self.add_widget(c1)
self.add_widget(c2)
def_update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
defon_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
classCircley(Widget):
def__init__(self, label='label', **kwargs):
super(Circley, self).__init__(**kwargs)
with self.canvas.before:
Color(0, 1, 0, 1) # This GREEN does not display
self.circ = Ellipse(
size=self.size,
pos=self.pos,
text=label
)
def_update_circ(self, instance, value):
self.circ.pos = instance.pos
self.circ.size = instance.size
defon_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
if __name__ == '__main__':
MyApp().run()
Post a Comment for "Nesting Widgets In Kivy"