nested boxlayout doesn't display background color where expected

754 views
Skip to first unread message

Max Fritzler

unread,
Aug 14, 2021, 7:16:01 PM8/14/21
to Kivy users support
I'm teaching myself kivy by modifying a card game, using the kvsol library for inspiration for the kivy gui part, and merging with rummy for the rules part.

This game is for 2-10 players.  Each player melds (lays down) cards in an area before them on the table, known as a tableau.  In the program there will be 1 human player, the rest robot players

I'm trying to achieve a tableau with a background color that is different for each player.  The idea is that the human needs to easily see which set of cards belong to which player.  So if the cards are say 85% the size the tableau, you'd see them as if they were laid on a cloth of that color.

What I get is this:

Screenshot 2021-08-14 175604.png

The tableau background color is the yellow. What I wanted and expected to happen was to see the yellow band going across the screen, with the buttons showing over it.  Once I got that working, I'd change the color a bit for each tableau (or band), here shown as a button and label.

I THINK the widget hierearchy is
FloatLayout (the root)
      top-menu
      board
            7 tableaus or bands, 6 defined as buttons within Python code and 1
            defined in the KV file
                       button n, Label n
      bottom menu

What is probably causing some of the trouble is my desire to dynamically generate the tableaus based on the variable number of players, 2-10.  So I'm trying to generate them in python code in a loop, rather than listing them in the kv file.

I have hypotheses regarding what is going wrong.
First, the tableau size and position seem to be defaulting to (100, 100) and (0, 0).  Ok, but the buttons are children of the tableau, and are being properly positioned by the size_hint.  But why is the rectangle in the tablea not also being positioned by that, instead of being positioned at the default?

Second, I thought that the tableau background color, set to yellow, was being completely covered up by the buttons.  But, based on the picture, I don't see how that could be true.

Third, maybe mixing the screen definition between pure python and KV is messing up the hierarchy.  Or, maybe something else.

I'm open to all suggestions, including abandoning the loop to generate the tableaus.  I guess I could stick all 10 in the KV file, default their size to zero, and then only size and enable enough to match the number of players chosen for the game. 

Or something else.

Any explanation of why my approach is wrongheaded, and what would be better, would be appreciated.

thanks in advance
build function.py
partial kv file.kv.txt

Elliot Garbus

unread,
Aug 15, 2021, 10:52:21 AM8/15/21
to kivy-...@googlegroups.com

I’ve created a small example to help address some of the concepts.  This is something I created for scratch after looking at your image and the code.

 

We want to create a class that represents the player.  We can style the player in kv, and put the code to execute the players acrions as methods for the player.  I’ve named this class Player.  I created the Player class, and in on_start(), after the kv code has been processed I am adding 3 players to the game board.

 

Looking at your image, the layout of the players are in a vertical stack, this is a good fit for a BoxLayout with vertical orientation, rather than a floatlayout.   I put a placeholder under the players so they start at the top of the screen.  The players have a fixed vertical height, so the placeholder fills the remaining space and pushes them to the top of the screen.

 

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.uix.label import Label


kv =
"""
#:set forest_green 34/255, 139/255, 34/255
#:set yellow .9, .9, 0

<Player>:
    size_hint_y: None
    height: dp(48)
    padding: 10
    canvas:
        Color:
            rgb: yellow
        Rectangle:
            pos: self.pos
            size: self.size
    Button:
        text: root.button_text
        size_hint_x: .25
    Label:
        text: root.label_text
        color: 'black'
       
BoxLayout:
    orientation: 'vertical'
    Label:                        
        text: 'Insert Player Test'
        size_hint_y: None
        height: dp(24)
    BoxLayout:
        orientation: 'vertical'
        canvas:
            Color:
                rgb: forest_green
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout:                # area for the players
            id: game_board
            orientation: 'vertical'
            spacing: dp(5)
    Button:
        text: 'Add Player'
        size_hint_y: None
        height: dp(48)
        on_release: app.add_player()
"""


class Player(BoxLayout):
    button_text = StringProperty()
    label_text = StringProperty()


class GameBoardApp(App):
    num_players =
0
   
max_players = 8

   
def build(self):
       
return Builder.load_string(kv)

   
def on_start(self):
       
# add 3 players by default... just an example
       
game_board = self.root.ids.game_board
       
for i in range(1, 4):
            player = Player(
button_text=f'Button {i}', label_text=f'Player {i}')
            game_board.add_widget(player)
       
self.num_players = 3
       
# to move the players to the top of the board, add a widget to take up the rest of the space
       
game_board.add_widget(Label(text='Placeholder, remove text for a blank space'))


   
def add_player(self):
        game_board =
self.root.ids.game_board
       
if self.num_players < self.max_players:
           
self.num_players += 1
           
i = self.num_players
            player = Player(
button_text=f'Button {i}', label_text=f'Player {i}')
            game_board.add_widget(player,
index=1# insert before placeholder


GameBoardApp().run()

 

 

 

 

 

 

From: Max Fritzler
Sent: Saturday, August 14, 2021 4:16 PM
To: Kivy users support
Subject: [kivy-users] nested boxlayout doesn't display background color where expected

 

I'm teaching myself kivy by modifying a card game, using the kvsol library for inspiration for the kivy gui part, and merging with rummy for the rules part.

 

This game is for 2-10 players.  Each player melds (lays down) cards in an area before them on the table, known as a tableau.  In the program there will be 1 human player, the rest robot players

 

I'm trying to achieve a tableau with a background color that is different for each player.  The idea is that the human needs to easily see which set of cards belong to which player.  So if the cards are say 85% the size the tableau, you'd see them as if they were laid on a cloth of that color.

 

What I get is this:


 

The tableau background color is the yellow. What I wanted and expected to happen was to see the yellow band going across the screen, with the buttons showing over it.  Once I got that working, I'd change the color a bit for each tableau (or band), here shown as a button and label.

 

I THINK the widget hierearchy is

FloatLayout (the root)

      top-menu

      board

            7 tableaus or bands, 6 defined as buttons within Python code and 1

            defined in the KV file

                       button n, Label n

      bottom menu

 

What is probably causing some of the trouble is my desire to dynamically generate the tableaus based on the variable number of players, 2-10.  So I'm trying to generate them in python code in a loop, rather than listing them in the kv file.

 

I have hypotheses regarding what is going wrong.

First, the tableau size and position seem to be defaulting to (100, 100) and (0, 0).  Ok, but the buttons are children of the tableau, and are being properly positioned by the size_hint.  But why is the rectangle in the tablea not also being positioned by that, instead of being positioned at the default?

 

Second, I thought that the tableau background color, set to yellow, was being completely covered up by the buttons.  But, based on the picture, I don't see how that could be true.

 

Third, maybe mixing the screen definition between pure python and KV is messing up the hierarchy.  Or, maybe something else.

 

I'm open to all suggestions, including abandoning the loop to generate the tableaus.  I guess I could stick all 10 in the KV file, default their size to zero, and then only size and enable enough to match the number of players chosen for the game. 

 

Or something else.

 

Any explanation of why my approach is wrongheaded, and what would be better, would be appreciated.

 

thanks in advance

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/c3975d0c-c488-4249-bb04-54cfac91ad2bn%40googlegroups.com.

 

Max Fritzler

unread,
Aug 17, 2021, 8:39:17 AM8/17/21
to Kivy users support
Many Many Thanks ElliotG!!!

Your example really helped me get some of the Kivy processing structure in my mind.  Particularly, where to manipulate the creation of the object (in the build method) and where to manipulate instances of the object (in the on_start and other on_... methods.)  After half a day of working with your example I have drastically cleaned up my code.  Another post helped me figure out how to dynamically change the colors in the on_start method.  I already had the Kivy settings features somewhat figured out.  So now I get just what I want, namely, the colored Player areas that automatically resize to fill available space and the number of players.  This is important so that the card images displayed in the various player bands are as large as possible.  See two screen shots below  (yes, I need to pick prettier colors):
Screenshot 2021-08-17 072757.png

And after changing settings to 8:

Screenshot 2021-08-17 072841.png

The next step is to follow the example in kvsol and deal cards into the player spaces.

Again,  many many thanks ElliotG!

Elliot Garbus

unread,
Aug 17, 2021, 10:20:37 AM8/17/21
to kivy-...@googlegroups.com

Glad to hear the example was helpful. 😊

It looks like you are on your way!

 

From: Max Fritzler
Sent: Tuesday, August 17, 2021 5:39 AM
To: Kivy users support
Subject: Re: [kivy-users] nested boxlayout doesn't display background colorwhere expected

 

Many Many Thanks ElliotG!!!

 

Your example really helped me get some of the Kivy processing structure in my mind.  Particularly, where to manipulate the creation of the object (in the build method) and where to manipulate instances of the object (in the on_start and other on_... methods.)  After half a day of working with your example I have drastically cleaned up my code.  Another post helped me figure out how to dynamically change the colors in the on_start method.  I already had the Kivy settings features somewhat figured out.  So now I get just what I want, namely, the colored Player areas that automatically resize to fill available space and the number of players.  This is important so that the card images displayed in the various player bands are as large as possible.  See two screen shots below  (yes, I need to pick prettier colors):

 

And after changing settings to 8:

 

Screenshot 2021-08-17 072841.png
Screenshot 2021-08-17 072757.png
Reply all
Reply to author
Forward
0 new messages