In the previous part we configured the app windows to be 1200 x 675 pixels in size so that we don’t have to worry about resizing the window anymore. In this part we’ll focus on adding some Kivy properties to our project. This way we’ll be able to refactor the code and make it way less repetitive and more readable.
But before we delve into the topic, here’s some info for you.
*****
Book Info
I just published my Kivy book, GUI Programming with Python and Kivy. It’s pretty long (over 800 pages) and comprehensive. And, which also counts, easy to read. The book contains lots of illustrations.
This book covers all the basics that you need to know to start programming GUI applications with Python and Kivy. Throughout the book we are building a GUI application from scratch, a fully functional game using all kinds of tools that Kivy has to offer. It’s our Slugrace project, but covered in a much more in-depth manner.
Each part of the book starts with a theoretical introduction of a topic or idea that we then implement in the project. I assume you have no prior knowledge of the Kivy library, but you should have at least some basic knowledge of the Python programming language, including the object-oriented programming paradigm as this is what we will be using a lot in this book.
The book covers all the basic elements of Kivy that you have to know, like widgets, layouts, Kivy ids and properties, graphics, screens, animation, sound. Finally we’ll deploy the app to Windows. It is pretty comprehensive and after you finish it, I’m sure you’ll be able to create your own awesome GUI apps of any kind, not just games.
I hope you will have at least as much fun reading the book as I had writing it.
As far as this Kivy series is concerned, the following parts will contain the most important elements covered in the book. However, some elements will be presented in a simplified way here on my blog or omitted completely.
____________
If you are interested, you can purchase the book in four versions. Here are the links:
1) ebook – pdf version on my website – in full color
Here you can see the description of the book, sample graphics from the book and the full table of contents.
2) ebook – Kindle version on Amazon – in full color
3) paperback version on Amazon – in black and white
4) paperback version on Amazon – in full color
*****
And Now Let’s Move On…
Let’s start with the Settings screen. There are a couple opportunities for us to make use of Kivy properties.
The Player Radio Buttons
In the settings.kv file you will find the following section:
# File name: settings.kv
...
<SettingsScreen>:
...
### THE PLAYERS ###
BoxLayout:
...
# Radiobuttons
BoxLayout:
size_hint: (.4, None)
height: 50
# 1 player
BoxLayout:
PlayerRadioButton:
RegularLabel:
text: '1 player'
# 2 players
BoxLayout:
PlayerRadioButton:
RegularLabel:
text: '2 players'
# 3 players
BoxLayout:
PlayerRadioButton:
RegularLabel:
text: '3 players'
# 4 players
BoxLayout:
PlayerRadioButton:
RegularLabel:
text: '4 players'
# Player name and initial money setup
...
This code is responsible for the radio buttons in the Players area where you will choose the number of players. As you can see the code for each player only differs in the label text. We could leave it as is because it isn’t much code and we will have to set the text for each label anyway, but let’s simplify it anyway, making use of Kivy properties.
So, now each player is represented by a BoxLayout with a PlayerRadioButton and RegularLabel. So, let’s create a class that inherits from BoxLayout and contains the two widgets. We can then create a StringProperty in the class and set the RegularLabel’s text to it. Then we can replace the code for each player in the code above by an instance of our class and just set the StringProperty there. But enough talking, let’s do it.
First let’s define the class in the Python file. Open the settings.py file and add the following code:
# File name: settings.py
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.config import Config
# Import the StringProperty.
from kivy.properties import StringProperty
# Configuration
Config.set('graphics', 'width', '1200')
Config.set('graphics', 'height', '675')
class PlayerCount(BoxLayout):
count_text = StringProperty('')
class SettingsScreen(BoxLayout):
pass
class SettingsApp(App):
def build(self):
return SettingsScreen()
if __name__ == '__main__':
SettingsApp().run()
As you can see, there’s the StringProperty that we can now use. Now, in the kv file let’s add a rule for the PlayerCount class:
# File name: settings.kv
...
# Here's our PlayerCount class that inherits from BoxLayout.
# There we have the PlayerRadioButton and RegularLabel.
# We can now set the text on the RegularLabel to the
# count_text StringProperty we just defined in Python.
<PlayerCount>:
PlayerRadioButton:
RegularLabel:
text: root.count_text
<SettingsScreen>:
...
And now we can replace each piece of code that represents one player by an instance of the PlayerCount class and set the count_text property accordingly:
# File name: settings.kv
### LABELS ###
...
<PlayerCount>:
PlayerRadioButton:
RegularLabel:
text: root.count_text
<SettingsScreen>:
...
### THE PLAYERS ###
...
# Radiobuttons
BoxLayout:
size_hint: (.4, None)
height: 50
# 1 player
PlayerCount:
count_text: '1 player'
# 2 players
PlayerCount:
count_text: '2 players'
# 3 players
PlayerCount:
count_text: '3 players'
# 4 players
PlayerCount:
count_text: '4 players'
# Player name and initial money setup
...
Now our code is a bit shorter and more readable. We’re using the instances of the PlayerCount class just like any other widgets.
The Player Settings
Now, further down in the settings.kv file there’s even more repetitive code. Scroll down until you see this section of the file:
# File name: settings.kv
...
<SettingsScreen>:
...
### THE PLAYERS ###
...
# Player name and initial money setup
...
# the players rows
# player 1
BoxLayout:
Regular80x30Label:
text: 'Player 1'
NameInput:
BoxLayout:
RegularLabel:
text: ""
size_hint_x: None
width: 280
DollarLabel:
NumInput:
# player 2
BoxLayout:
Regular80x30Label:
text: 'Player 2'
NameInput:
BoxLayout:
RegularLabel:
text: ""
size_hint_x: None
width: 280
DollarLabel:
NumInput:
# player 3
BoxLayout:
Regular80x30Label:
text: 'Player 3'
NameInput:
BoxLayout:
RegularLabel:
text: ""
size_hint_x: None
width: 280
DollarLabel:
NumInput:
# player 4
BoxLayout:
Regular80x30Label:
text: 'Player 4'
NameInput:
BoxLayout:
RegularLabel:
text: ""
size_hint_x: None
width: 280
DollarLabel:
NumInput:
### ENDING CONDITIONS ###
...
Here again each player is represented by their own piece of code. So, for each player we have a BoxLayout with a Regular80x30Label, a NameInput, and another BoxLayout with three further widgets. The code is pretty much the same for each player. What differs is the text on the Regular80x30Label. So, you probably also have this feeling that this could be simplified. So, let’s do it in a similar way like with the radio buttons. First, let’s define a class in the Python file that inherits from BoxLayout and define a StringProperty on it:
# File name: settings.py
...
class PlayerCount(BoxLayout):
count_text = StringProperty('')
class PlayerSettings(BoxLayout):
label_text = StringProperty('')
class SettingsScreen(BoxLayout):
pass
class SettingsApp(App):
...
And now let’s add the following rule in the kv file:
# File name: settings.kv
...
<PlayerCount>:
...
<PlayerSettings>:
Regular80x30Label:
text: root.label_text
NameInput:
BoxLayout:
RegularLabel:
text: ""
size_hint_x: None
width: 280
DollarLabel:
NumInput:
<SettingsScreen>:
...
With that in place, we are ready to replace each player’s BoxLayout with an instance of the PlayerSettings class. All we have to do is set the label_text property:
# File name: settings.kv
...
<PlayerCount>:
...
<PlayerSettings>:
Regular80x30Label:
text: root.label_text
NameInput:
BoxLayout:
RegularLabel:
text: ""
size_hint_x: None
width: 280
DollarLabel:
NumInput:
<SettingsScreen>:
...
### THE PLAYERS ###
...
# Player name and initial money setup
BoxLayout:
...
# the players rows
# player 1
PlayerSettings:
label_text: 'Player 1'
# player 2
PlayerSettings:
label_text: 'Player 2'
# player 3
PlayerSettings:
label_text: 'Player 3'
# player 4
PlayerSettings:
label_text: 'Player 4'
### ENDING CONDITIONS ###
...
Now the code became much shorter and more readable. If you run the app, it will work as before.
That’s it for now as far as the Settings screen is concerned. In the next part we’ll create similar classes with Kivy properties for the Race screen.