2

White Box Error Kivy

I am trying to create a program that outputs random 10x10 grids of black and white squares. It mostly works except that the bottom left corner has an unwanted white square covering up part of the grid.

I can't even figure out what widget would be causing this. I've tried printing all of the children starting at root to no avail.

import random
import kivy
kivy.require("1.10.1")
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.config import Config
from kivy.graphics import Color
from kivy.graphics import Rectangle


Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '400')

class Container(FloatLayout):
    pass

class ColorLabel(Label):
    def __init__(self, **kwargs):
        super(ColorLabel, self).__init__(**kwargs)

        with self.canvas:
            Color(1, 1, 1, 1)
            self.rect = Rectangle(size=self.size, pos=self.pos)

        self.bind(size=self._update_rect, pos=self._update_rect)

    def _update_rect(self, instance, value):
        self.rect.pos = instance.pos
        self.rect.size = instance.size

    def changeBG(self):
        with self.canvas.after:
            Color(0,0,0,1)
            self.rect = Rectangle(size=self.size, pos=self.pos)

class Main(App):
    def build(self):
        Builder.load_file("EveryImage.kv")
        the_grid = GridLayout(cols=10, spacing=1)

        i = 100
        while i > 0:
            i -= 1
            newLabel = ColorLabel()
            the_grid.add_widget(newLabel)
            x = random.randint(0,1)
            if x == 0:
                newLabel.changeBG()

        root = Container()
        root.add_widget(the_grid)           
        return root

# Keep everything below this last!      
if __name__ == '__main__':
    Main().run()

And here is the .kv file:

#EveryImage.kv
Container:

#Container holds all the other layouts
<Container>:
    id: contain
    canvas.before:
        Color:
            rgba: 0,0,0.5,1 #blue, just for the grid
        Rectangle:
            pos: self.pos
            size: self.size

<ColorLabel>:
    canvas.before:
        Color:
            rgba: 1,1,1,1 #white
        Rectangle:
            pos: self.pos
            size: self.size
Plug Fire
  • 127
  • 10

1 Answers1

3

The problem is that you are painting several times in different places, precisely in the function changeBG, instead you just have to paint in one place and set the background color as property so when this value is changed the Label will be repainted.

Another error is that you are creating a Container that you do not use in the .kv.

In the case of the while loop this can be simplified using a for loop.

*.py

import random

import kivy
kivy.require("1.10.1")
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.config import Config

Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '400')

class Container(FloatLayout):
    pass

class ColorLabel(Label):
    pass

class Main(App):
    def build(self):
        Builder.load_file("EveryImage.kv")
        the_grid = GridLayout(cols=10, spacing=1)
        for _ in range(100):
            newLabel = ColorLabel()
            the_grid.add_widget(newLabel)
            if random.choice([True, False]):
                newLabel.bg_color = [0,0,0,1]
        root = Container()
        root.add_widget(the_grid)           
        return root

# Keep everything below this last!      
if __name__ == '__main__':
    Main().run()

*.kv

#Container holds all the other layouts
<Container>:
    id: contain
    canvas.before:
        Color:
            rgba: 0,0,0.5,1 #blue, just for the grid
        Rectangle:
            pos: self.pos
            size: self.size

<ColorLabel>:
    bg_color: 1, 1, 1, 1
    canvas.before:
        Color:
            rgba: self.bg_color # white
        Rectangle:
            pos: self.pos
            size: self.size

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I keep getting an error in line 15 of the kv file: "TypeError: 'NoneType' object is not iterable". – Plug Fire Jan 16 '19 at 03:12
  • @PlugFire I have updated the code, it seems that the kv interpreter has problems with the comments, try it again and tell me if the error continues – eyllanesc Jan 16 '19 at 03:18
  • Yes! Thank you so much! I was banging my head against the wall trying to figure this out! – Plug Fire Jan 16 '19 at 03:21