Skip to content
Home » Kivy Part 43 – Slugrace – Screen Managers

Kivy Part 43 – Slugrace – Screen Managers

Spread the love

Hey guys, in the previous part of the series we turned our so-called screens into real screens. To work with screens, we need screen managers, two in our case, but generally at least one screen manager is necessary.

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…

The ScreenManager Class

A screen manager is an object of the ScreenManager class that handles the transitions from one screen to another. 

In our app we will need two screen managers. The first one will switch between the Settings screen, Race screen and Game Over screen. These are the screens that will take up the whole space of the app window. But then we’ll need another screen manager that will switch between the Bets screen and the Results screen inside the Race screen.

We’re going to take care of the former in this part of the series and handle the latter in the next part.

The main.py File

When you open the main.py file, you will see the following code:

# File name: main.py

import kivy
from kivy.app import App

class SlugraceApp(App):
    def build(self):
        pass    

if __name__ == '__main__':
    SlugraceApp().run()

This is actually the place where our app will start. When our screen system is up and running, we won’t be running the five screens separately, as we’re doing now, but rather from one location, which is right here.

The build method must return something. It’s going to return a ScreenManager object that we’re just about to create. So, here’s how we do it:

# File name: main.py

import kivy
from kivy.app import App

# We need to import the ScreenManager class.
from kivy.uix.screenmanager import ScreenManager

# We'll also add the configuration code here, 
# so we must import the Config class, like we did
# in all the other Python files before.
from kivy.config import Config

# Here's the configuration.
Config.set('graphics', 'width', '1200')
Config.set('graphics', 'height', '675') 
Config.set('graphics', 'resizable', '1')

# Now we must define a screen manager class that 
# inherits from ScreenManager.
class SlugraceScreenManager(ScreenManager):
    # We'll implement it in the kv file.
    pass

class SlugraceApp(App):
    def build(self):
        # The method should return the screen manager.
        return SlugraceScreenManager()    

if __name__ == '__main__':
    SlugraceApp().run()

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

When we run the app now, we will see just a black app window. This is because a ScreenManager is returned that hasn‘t been implemented yet. We’re going to implement it in the kv file. As you can see, the name of the app is SlugraceApp, so, following the naming convention discussed before, the kv file should be called slugrace.kv. So, let’s create the file and put the following code in it:

# File name: slugrace.kv

# Here's our screen manager. It should contain 
# the three full-window screens. Each screen 
# must have a name so that we can then
# reference it.
<SlugraceScreenManager>:     
    SettingsScreen:
        name: 'settingsscreen'
    RaceScreen:
        name: 'racescreen'
    GameoverScreen:
        name: 'gameoverscreen'

In the code above you can see that our screen manager widget contains three screens. By default it will use the first one, so SettingsScreen. But there are still a couple of things we must do. First of all we must load the kv files of the three screens in the Python file. Second, we must import the Python files in the kv files, which is something new that we haven’t done before. So, let’s start with the former, we already did it before:

# File name: main.py

import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager
from kivy.config import Config

# We need the Builder class to load kv files.
from kivy.lang import Builder

# Configuration
Config.set('graphics', 'width', '1200')
Config.set('graphics', 'height', '675') 
Config.set('graphics', 'resizable', '1')

# We must load the kv files of the three screens.
Builder.load_file('settings.kv')
Builder.load_file('race.kv')
Builder.load_file('gameover.kv')

class SlugraceScreenManager(ScreenManager):
    pass

class SlugraceApp(App):
    def build(self):
        return SlugraceScreenManager()    

if __name__ == '__main__':
    SlugraceApp().run()

But this is not enough for the app to work. If tou ran it now, you would get errors informing you that SettingsScreen, RaceScreen and GameoverScreen are unknown classes. So, now we have to inform the corresponding kv files what they are, which we do by importing the Python files in the kv files.

Importing in kv File

To import Python modules and classes in the Kivy language, there’s a special syntax for that:

#:import alias name

It looks like a comment, but as you can see there’s a colon folowing the # sign. Unlike in Python code, the alias comes first and only then the name of the module or class without the .py extension. So, for example if you wanted to import the numpy module, you would do it like so:

#:import np numpy

This is equivalent to:

import numpy as np

in Python.

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

So, now that you know how to import stuff in kv, we can import the Python files. In kv we must use an alias, which is not required in Python, so often you just repeat the name of the module as the alias in Kivy. This is how we are going to import the settings.py file in the settings.kv file:

#:import settings settings

So, we’re importing the settings module with the alias settings. Now the settings.kv file should look like this:

# File name: settings.kv
#:import settings settings

<PlayerCount>:
    ...

<PlayerSettings>:
    ...

<SettingsScreen>:
    ...

Similarly, let’s import the appropriate modules in the other two kv files. Here’s the race.kv file:

# File name: race.kv
#:import race race

<SlugStats>:     
    ...

<PlayerStats>: 
    ...

<SlugInfo>:
    ...

<SlugImage>:
    ...

<RaceScreen>:
    ...

And here’s the gameover.kv file:

# File name: gameover.kv
#:import gameover gameover

<GameoverScreen>: 
    ...

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.

So, with the modules imported, the screen manager should display the first screen on its list, so the Settings screen. Here’s what we get when we run the app from the main.py file:

settings screen

Although the app works, in the terminal you can see quite a few errors and warnings. Some of them are related to the fact that the widgets.kv file is loaded multiple times. We’ll handle this in the one of the following parts of the series. And now let’s make the screen manager actually switch the screens.

Switching Screens

As I said, the first screen in the screen manager is used by default if not otherwise specified. But how do we switch to another screen? When we press the Ready button in the Settings screen, we want to switch to the Race screen. To do that we must somehow reference the screen manager and set its current property to the name of the screen. You can access a screen’s manager by using the manager property on the Screen object. Each screen has the manager property which is used to access the instance of the screen manager.

So, in the settings.kv file let’s locate the Ready button and set the manager’s current property to indicate the Race screen. We have to use the name of the screen that we defined before:

# File name: settings.kv
#:import settings settings

...

<SettingsScreen>:
    ...

        ### READY BUTTON ###
        RedButton:
            text: 'Ready'
            on_press: root.manager.current = 'racescreen'

Now if you run the app (from now on we’ll be always running the app from the main.py file), the Settings screen will appear again. Let’s press the Ready button and we should switch to the Race screen. And now let’s make the screen manager switch to the Game Over screen when we press the End Game button in the Race screen. You will find the code in the race.kv file. Here’s what we have to add:

# File name: race.kv
#:import race race

...

<RaceScreen>:
    ...                         
            
            # Buttons
            BoxLayout:
                ...
                
                RedButton:
                    text: 'End Game'  
                    pos_hint: {'right': 1}
                    on_press: root.manager.current = 'gameoverscreen'

                RedButton:
                    ...

Now when you run the app and press the Ready button, you will switch to the Race screen. In the Race screen you can now press the End Game button and you will switch to the Game Over screen.

Finally, in the Game Over screen, we want to switch back to the Settings screen when the Play Again button is pressed, which will also close the cycle of switches between screens in our app, at least the full-window screens. Here’s the code in the gameover.kv file:

# File name: gameover.kv
#:import gameover gameover

<GameoverScreen>: 
    ...
        
        # The buttons
        BoxLayout: 
            ...    

            RedButton:
                text: 'Play Again'
                pos_hint: {'x': 0, 'center_y': .5}
                on_press: root.manager.current = 'settingsscreen'

            RedButton:
                ...

Try it out. You should now be able to switch from the Settings screen to the Race screen, from the Race screen to the Game Over screen and from the Game Over screen back to the Settings screen. We’re not yet done with the code, there’s quite a lot of code to refactor, which we’ll take care of later on, but now, in the next part of the series, we will implement the other screen manager, so the one that switches between the Bets screen and the Results screen inside the Race screen.


Spread the love

1 thought on “Kivy Part 43 – Slugrace – Screen Managers”

Leave a Reply