'Drawing a an array of rectangles on the screen using kivy language in python file
I'm trying to draw a array of rectangles, which could be dynamically changed (that's something not implemented yet).
The expected behavior is having a orange rectangle all along the top of the screen (for future add some labels), and then the array of rectangles blue and green. But instead the top orange rectangle doesn't show and the array of green and blue displays only in the 100x100 canvas with a weird extension on the edges.
Any advice?
Python file:
from kivy.app import App
from kivy.graphics import Color, Rectangle
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import ListProperty, NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
class cell(Widget):
color = ListProperty([1, 1, 1, 1])
def __init__(self, number, **kwargs):
super(cell, self).__init__(**kwargs)
self.number = number
self.update_color()
def update_color(self):
if self.number == 1:
self.color = (0, 1, 0, 1)
else:
self.color = (0, 0, 1, 1)
def resize(self, pos, size):
self.pos = pos
self.size = size
class game_screen(Screen):
neighbors = [(0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)]
screen_width = NumericProperty(0)
screen_height = NumericProperty(0)
def __init__(self, **kwargs):
super(game_screen, self).__init__(**kwargs)
self.x_size = 5
self.y_size = 7
self.world = self.new_world(self.x_size, self.y_size)
self.resize(self.world)
def new_world(self, x, y):
world = [["" for i in range(y)] for j in range(x)]
return world
def resize(self, world):
self.cell_size = (self.screen_width / self.x_size, self.screen_height / self.y_size)
main_layout = BoxLayout(size=self.size, orientation='vertical')
top_info = RelativeLayout(size_hint=(1, None), size=(self.width, dp(50)))
with self.canvas:
Color(1, .5, 0, 1)
self.rect= Rectangle(size=(self.width, self.height), pos=self.pos)
self.bind(pos=self.update_rect,
size=self.update_rect)
main_layout.add_widget(top_info)
world_layout = RelativeLayout(size=self.size)
for i in range(len(world)):
for j in range(len(world[0])):
print (f'x:{i}, y:{j}')
num = i + j
if num % 2 == 0:
numero = 1
else:
numero = 0
position = (self.cell_size[0] * i, self.cell_size[1] * j)
celula = cell(numero)
celula.update_color()
celula.resize(pos=position, size=self.cell_size)
world[i][j] = celula
world_layout.add_widget(celula)
main_layout.add_widget(world_layout)
self.add_widget(main_layout)
def update_rect(self, *args):
self.rect.pos = (0, self.height-dp(50))
self.rect.size = (self.width, dp(50))
Builder.load_file("CellWorld.kv")
class GameOfLifeApp(App):
sm = None
def build(self):
self.sm = ScreenManager()
self.sm.add_widget(game_screen(name="game"))
return self.sm
GameOfLifeApp().run()
Kivy file, honestly I'm not really sure I need 'screen_width' and 'screen_height'. I was using it for testing solutions I found on other codes while trying to solve this issue.
<game_screen>:
screen_width: self.width
screen_height: self.height
<cell>:
canvas:
Color:
rgba: self.color
Rectangle:
pos: self.pos
size: self.size
Solution 1:[1]
The problem is that the size that you set for your Cell widgets is being ignored, because size_hint takes precedence over size. Just add size_hint: None, None to your kv in the <Cell>: rule:
<cell>:
size_hint: None, None
canvas:
Color:
rgba: self.color
Rectangle:
pos: self.pos
size: self.size
You should also delay calling the resize() method until the game_screen gets its size set. You can use Clock.schedule_once() to accomplish this. First remove self.resize(self.world) from the game_screen __init__() method, Then add the Clock.schedule_once() call to the build() method:
def build(self):
self.sm = ScreenManager()
gs = game_screen(name="game")
self.sm.add_widget(gs)
Clock.schedule_once(partial(gs.resize, gs.world))
return self.sm
And modify the signature of resize() to handle the extra arg added by the Clock.schedule_once():
def resize(self, world, *args):
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

