Alvaro Alvaro - 3 months ago 14
Python Question

<Python - Kivy > GridLayout rendering a single Tile

I have the following python classes:

import os

from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image

from crawler.settings import ASSETS_DIR


class Map(GridLayout):
SIZE = 5

def __init__(self, **kwargs):
super(Map, self).__init__(**kwargs)
for _ in range(0, self.SIZE**2):
self.add_widget(Tile())


class Tile(Widget):
def __init__(self, **kwargs):
super(Tile, self).__init__(**kwargs)
self.add_widget(Image(source=os.path.join(ASSETS_DIR, 'images/chest.gif')))


And the following kv language definition:

#:kivy 1.0.9

<Map>:
size: self.parent.size

<Tile>:
size: 20, 20


This only renders 1 chest (actually the loop runs ok, so maybe they're stacked?):
enter image description here
While if I change the Tile class for some of the out-of-the-box Widgets like a Button:

class Map(GridLayout):
SIZE = 5

def __init__(self, **kwargs):
super(Map, self).__init__(**kwargs)
for _ in range(0, self.SIZE**2):
self.add_widget(Button(text=str(_)))


It displays the correct result:
enter image description here

What am I missing in my Tile class to make this work? I think that's where the problem is, but I couldn't find it so far

Answer
class Tile(Widget):
    def __init__(self, **kwargs):
        super(Tile, self).__init__(**kwargs)
        self.add_widget(Image(source=os.path.join(ASSETS_DIR, 'images/chest.gif')))

Each Tile is a Widget containing an Image, but Widget isn't a layout class so the Image just has the default pos of (0, 0) and size of (100, 100).

You could instead make the Tile be the Image, or replace Widget with a layout like BoxLayout (this latter choice will be less efficient unless you need the extra layout behaviour).

Comments