How can I get widget's/layout's actual size in Kivy?

kivy, layout, python-3.4, python-3.x, widget

Solution

Size of widget depends on when you're checking. Size isn't calculated when widget is created but when it's placed inside Layout. For example:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.layout import Layout

kv = '''
<Foo>:
    on_touch_down: print(self.size)
'''
Builder.load_string(kv)

class Foo(Layout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        print (self.size)

class MyApp(App):
    def build(self):
        return Foo()

MyApp().run()

Inside `__init__()` method value of size is still (100, 100). Clicking on widget later, after it's been placed, will return proper value.

If you want, you can bind widget size to a method, which will be called after resizing:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.layout import Layout

class Foo(Layout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.bind(pos=self.update)
        self.bind(size=self.update)
        self.update()

    def update(self, *args):
        print(self.size)
        self.canvas.clear() 
        with self.canvas:
            pass

class MyApp(App):
    def build(self):
        return Foo()

MyApp().run()

First, `Foo` is created with default size value. Then it's displayed, so proper size value is calculated and assigned to size property, which triggers `update` method. Any other updating of size (for example if you rescale window) will also triger this method. Kivy language does this automathically and it's recommended method.

Lastly, I don't know what you're trying to achieve but I suspect you don't really need this value right away.

Problem

I have this layout inside BoxLayout (along with another elements): ``` <PlayField>: size_hint_x: None width: self.height canvas.before: Color: rgb: .9, .9, .9 Rectangle: pos: self.pos size: self.size ``` main.py: ``` class PlayField(Layout): # Or should it be Widget? pass ``` How do I get actual size of it? `print(self.size)` shows default size (100, 100), although it's not true.

Original source