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.
class MyApp(App):
title = 'My App'
def build(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
class MyApp(App):
title = 'My App'
def build(self):
root = RootWidget()
root.bind(
size=root._update_rect,
pos=root._update_rect)
return root
class RootWidget(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
class Background(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
class Holder(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
def on_touch_down(self, touch):
rcolor = Color(random(), random(), random(), 1)
with self.canvas:
self.color = rcolor
class Circley(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
def on_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"