Good Kivy Tutorial

Github Repository with follow along code: http://bit.ly/2ttDcjH

 

Kivy (Kind Of) pushMatrix and popMatrix Tutorial.

I was working with Kivy and having a hard time visualizing pushMatrix and popMatrix. Although this tutorial is using Javascript, he first 5 minutes is great for visualizing what pushMatrix and popMatrix do on a Kivy canvas.

Python OOP Tutorial 1: Classes and Instances by Corey Schafer

Kivy For The Non Computer Scientist – Part 17: Making Natural Looking GUI’s Using Kivy’s Float Layout.

In this blogpost we’ll look at how one can create more natural looking GUI’s by employing a background graphic and Kivy’s float layout. The post will also provide complete code and a background graphic, that place buttons and labels in precise locations for a 720p Jukebox interface. The interface is from the open source Convergence Jukebox project. The interface will appear as follows;

converge

Some things to understand before proceeding.

  • The GUI shown above and the code provided require that the graphic be rendered at 720p.
    • Only at 720p will all of the labels and buttons to line up appropriately in this example.
    • Assuming your display can handle 720p the GUI will render to that resolution when the code is run.
  • Float Layouts have unique properties in that;
    • Kivy Buttons and Labels (widgets) can be placed anywhere on the GUI.
    • Each widget type can be given both common and unique properties when deployed on the GUI itself.

The code for the above GUI is as follows;


import kivy
kivy.require("1.9.1")  # Used to alert user if this code is run on an earlier version of Kivy.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.core.window import Window  # Used to set Window to set window size and full screen

Window.fullscreen = False  # Does not force full screen
Window.size = (1280, 720)  # Sets 720p

Builder.load_string('''
<Label>: # Sets generic properties for Label instances. Can be overridden by changing properties in specific instance.
	color: 0,.7,0,1 # Sets Label generic text colour to green.
	font_size: 18 # Sets Label generic text font size to 18.
	valign: 'middle' # Sets Label generic text vertical alignment to middle.
	halign: 'left' # Sets Label generic text horizontal alignment to left.
	text_size: self.size # Forces text to be wrapped to fit Label size.
<Button>: # Sets generic properties for Button instances. Can be overridden by changing properties in specific instance.
	font_size: 18 # Sets Button generic font size to 18.
	color: 1,1,1,1 # Sets Button generic colour to white.
    bold: True # Sets Button generic text property to bold.
    background_normal: "" # Resets Button background default to plain.
    background_color: (0.0, 0.0, 0.0, 0.0) # Sets Button generic background colour to transparent.
    halign: 'center' # Sets Button generic horizontal alignment to center.
    valign: 'middle' # Sets Button generic vertical alignment to middle.
	text_size: self.size # Sets Button generic text to be wrapped to fit Button size.
	size_hint: .255, .0620 # Sets Button generic size.
<FloatLayout>:  # Creates a FloatLayout
    canvas.before:
        BorderImage: # Used to display background image.
            source: 'jukebox.png' # Background image filename.
            pos: self.pos # Positions image to take up 100% of layout.
            size: self.size # Positions image to take up 100% of layout.
	Label: # Creates an instance of Label on GUI. Properties below overide generic settings on this Label instance only.
	    id: sort_mode  # Identifies Label as sort_mode
	    text: "Sort Mode By Artist" # Text for this Label.
	    font_size: 38 # Overrides generic Label font size to 38 for this Label only.
	    halign: 'center' # Overrides generic Label horizontal alignment to center for this Label only.
	    size_hint: .3, 1 # Overrides generic Label size for this Label only.
		pos: 12,280 # Positions this label.
	Label: # Creates an instance of Label on GUI. Properties below overide generic settings on this Label instance only.
	    id: play_mode  # Identifies Label as sort_mode
	    text: "Mode: play_mode" # Text for this Label.
		pos: 40,245 # Positions this label.
	Label:
	    id: title_song
	    text: "Title: title_song"
		pos: 40,225
	Label:
	    id: title_artist
	    text: "Artist: title_artist"
		pos: 40,205
	Label:
	    id: title_year
	    text: "Year: 2017"
	    size_hint: 0.35, 1
		pos: 40,185
	Label:
	    id: title_length
	    text: "Length: title_length"
		pos: 135,185
	Label:
	    id: title_album
	    text: "Title: title_album"
		pos: 40,165
	Label:
	    id: sort_mode
	    text: "UPCOMING SELECTIONS"
	    font_size: 28
	    halign: 'center'
	    size_hint: .32, 1
		pos: 1,131
	Label:
	    id: selection_one
	    text: "selection_one"
		pos: 40,102
	Label:
	    id: selection_two
	    text: "selection_two"
		pos: 40,81
	Label:
	    id: selection_three
	    text: "selection_three"
		pos: 40,60
	Label:
	    id: selection_four
	    text: "selection_four"
		pos: 40,40
	Label:
	    id: selection_five
	    text: "selection_five"
		pos: 40,19
	Label:
	    id: selection_six
	    text: "selection_six"
		pos: 40,-1
	Label:
	    id: selection_seven
	    text: "selection_seven"
		pos: 40,-21
	Label:
	    id: selection_eight
	    text: "selection_eight"
		pos: 40,-41
	Label:
	    id: selection_nine
	    text: "selection_nine"
		pos: 40,-61
	Label:
	    id: selection_ten
	    text: "selection_ten"
		pos: 40,-81
	Label:
	    id: selection_eleven
	    text: "selection_eleven"
		pos: 40,-101
	Label:
	    id: selection_twelve
	    text: "selection_twelve"
		pos: 40,-121
	Label:
	    id: selection_thirteen
	    text: "selection_thirten"
		pos: 40,-141
	Label:
	    id: selection_fourteen
	    text: "selection_fourteen"
		pos: 40,-161
	Label:
	    id: selection_fifteen
	    text: "selection_fifteen"
		pos: 40,-181
	Label:
	    id: selection_sixteen
	    text: "selection_sixteen"
		pos: 40,-201
	Label:
	    id: credit_count
	    text: "CREDITS 0"
	    font_size: 34
	    halign: 'center'
	    size_hint: .3, 1
		pos: 12,-236
	Label:
	    text: "Twenty-Five Cents Per Selection"
	    halign: 'center'
	    size_hint: .3, 1
		pos: 12,-267
	Label:
	    id: selections_available
	    text: "selections_available"
	    halign: 'center'
	    size_hint: .3, 1
		pos: 12,-287
	Label:
	    id: jukebox_name
	    text: "Convergence Music System 2.0"
	    color: 0,0,0,1 # Sets text colour to black.
	    font_size: 38
	    bold: True
	    halign: 'center'
	    size_hint: .7, 1
		pos: 390,292
	Label:
	    id: song_name
	    text: "song_name"
	    color: 1,1,1,1 # Sets text colour to white.
	    font_size: 40
	    bold: True
	    halign: 'center'
	    size_hint: .7, 1
		pos: 390,230
	Label:
	    id: artist_name
	    text: "artist_name"
	    color: 1,1,1,1 # Sets text colour to white.
	    font_size: 40
	    bold: True
	    halign: 'center'
	    size_hint: .7, 1
		pos: 390,180
    Button: # Creates an instance of Button on GUI. Properties below overide generic settings on this Button instance only
	    id: song_0  # Identifies Button as song_0.
	    text: "song_0(Name)\\nsong_0(artist)" # Text for button includes line break.
		pos: 495,445 # Positions Button on GUI.
	Button:
	    id: song_1
	    text: "song_1(Name)\\nsong_1(artist)"
		pos: 495,390
	Button:
	    id: song_2
	    text: "song_2(Name)\\nsong_2(artist)"
		pos: 495,335
	Button:
	    id: song_3
	    text: "song_3(Name)\\nsong_3(artist)"
		pos: 495,280
	Button:
	    id: song_4
	    text: "song_4(Name)\\nsong_4(artist)"
		pos: 495,225
	Button:
	    id: song_5
	    text: "song_5(Name)\\nsong_5(artist)"
		pos: 495,170
	Button:
	    id: song_6
	    text: "song_6(Name)\\nsong_6(artist)"
		pos: 495,115
	Button:
	    id: song_7
	    text: "song_7(Name)\\nsong_7(artist)"
		pos: 495,60
	Button:
	    id: song_8
	    text: "song_8(Name)\\nsong_8(artist)"
		pos: 835,445
	Button:
	    id: song_9
	    text: "song_9(Name)\\nsong_9(artist)"
		pos: 835,390
	Button:
	    id: song_10
	    text: "song_10(Name)\\nsong_10(artist)"
		pos: 835,335
	Button:
	    id: song_11
	    text: "song_11(Name)\\nsong_11(artist)"
		pos: 835,280
	Button:
	    id: song_12
	    text: "song_12(Name)\\nsong_12(artist)"
		pos: 835,225
	Button:
	    id: song_13
	    text: "song_13(Name)\\nsong_13(artist)"
		pos: 835,170
	Button:
	    id: song_14
	    text: "song_14(Name)\\nsong_14(artist)"
		pos: 835,115
	Button:
	    id: song_15
	    text: "song_15(Name)\\nsong_15(artist)"
		pos: 835,60

''')

class RootWidget(FloatLayout):
    pass

class MainApp(App):
    def build(self):
        return RootWidget()

MainApp().run()

You’ll also need this graphic and ensure its named jukebox.png and it’s placed in the same directory as the above code;

jukebox

You can download this graphic by right mouse clicking and performing a Save As or by clicking on the link above.

Here are some of the new items you’ll find in the code;

  • Lines 12 and 18 – These lines establish generic properties for first the Label instances (line 12 and below) and then the Button instances (line 18 and below) when they are called.
    • In FloatLayouts these generic properties can be overridden by changing properties when a specific instance is established.
    • By setting up generic properties in this manner, the KV Language code is reduced significantly when instances are called.
      • In this app 45 instances of Buttons and Labels are created.
    • All lines involved in establishing the generic properties have comments as to what they do.
  • Line 23 – Code that sets Button generic background colour to transparent.
  • Lines 29 thru 33 – Code places and sets up GUI’s background image.
    • Comments provide insight into role each property plays
  • Lines 34 thru 40 – Code lays out first Label on Gui. Lines are commented so you know what function they play.
    • Any properties declared on these lines that match generic properties, override generic settings for this instance only.
  • Lines 39 and 40 – size_hint and pos properties work in concert with one another to set Label position. size_hint sets size of Label. pos positions top left corner of label.
    • Positioning is one of the hardest things to explain in a FloatLayout. I just kept changing both the size_hint and pos values until Labels lined up.
  • Lines 41 thru 44 – Code lays out second Label on Gui. Comments define what each line of code does.
  • Lines 45 thru 245 – Code for the remainder of Labels and Buttons on Gui following principles outlined above.
  • Lines 182 – 185 – Code for first Button placed on GUI.
  • Line 184 – Text for button using a line break.

To conclude the great thing about using a FloatLayout is the ability to place a widget with great accuracy on your Kivy GUI. As well, the use of a background image and transparent button overlays as performed in this example makes for a much more natural looking interface for your user.

In this case we have a layout that displays all of the widget’s object names. Based on what was presented in earlier blogposts in this series, the Buttons and Labels texts can be updated accordingly as well as callbacks added to buttons to provide the desired functionality.

Happy coding,

….brad….

How to change font in Kivy using LabelBase

Kivy For The Non Computer Scientist – Part 16: Reading Text From Kivy Buttons Created In KV Language For Use In Python Code.

When I wrapped up writing Kivy For The Non Computer Scientist – Part 15: Interacting With Python, one thing that eluded me was that I could not read and use the text from a button that was created in KV Language. This blog post comes with complete working Kivy code that will allow one to print the text on a Kivy button to its Python console.

In this instance the text is read and copied into a Kivy TextInput Widget when appropriate buttons are pressed. When the Print To Console button is pressed, the text displayed in the TextInput widget is passed to python as a string through an event and printed on the Python console. The app looks and works as follows;untitled-presentation

The complete working Kivy code to accomplish this (with comments) is as follows

import kivy
kivy.require("1.9.1") # used to alert user if this code is run on an earlier version of Kivy.
from kivy.app import App # imports Kivy App
from kivy.uix.gridlayout import GridLayout # imports GridLayout for use in app
from kivy.lang import Builder  # Imports the KV language builder that provides the layout of kivy screens

Builder.load_string(""" # KV Language string.
<ReadButtonTextGridLayout>: # Identifies layout/interactivity for the App.
    id: pad # ID's GridLayout as pad
    rows: 1 # Sets GridLayout row property to 1.
    GridLayout: # Row 1 layout
        rows: 3 # Sets GridLayout row property to 1.
        Button: # Creates a Buttin widget instance
            id: button1 # ID's Button as button 1
            text: "Hello, world!" # Text for above button.
            on_press:
                pad.my_buttons_text(button1.text)# on_press is a Kivy mouse release event.
        Button: # Creates a Buttin widget instance
            id: button2 # ID's Button as button 2
            text: "Hello, world! I'm here!" # Text for above button.
            on_press:
                pad.my_buttons_text(button2.text)# on_press is a Kivy mouse release event.
        Button: # Creates a Buttin widget instance
            id: button3 # ID's Button as button 3
            text: "Goodbye, world! I'm gone!" # Text for above button.
            on_press:
                pad.my_buttons_text(button3.text)# on_press is a Kivy mouse release event.
""")

class ReadButtonTextGridLayout(GridLayout): # Houses event handlers and directs a GridLayout for the <ReadButtonTextGridLayout> class.

    def my_buttons_text(self, my_text): # my_button_text event handler code
        print(str(my_text)) # my_text printed to Python console.

class ButtonReadingApp(App): # Creates the instance (copy) of the Kivy App class named ButtonReadingApp

    def build(self):# build is a method of Kivy's App class used to place widgets onto the GUI.
        return ReadButtonTextGridLayout() # return calls the build method which in turn builds the GUI.

ButtonReadingApp().run() # Runs ButtonReadinApp

There is not much new to the code here that has not been covered in previous posts so let me get to the highlights.

  • Line 8 – This is the first kv Language code that defines the class in KV Language that does not start immediately with it’s GridLayout designation. The GridLayout is called on Line 41 when a GridLayout is applied as the ReadButtonTextGridLayout class is initiated.
  • Line 9 – The entire GUI is id’d as pad. That pad id is used on the event called on Line 36 to identify the text to be sent to the event handler that ultimately prints the text to Pythons console.
  • Lines 12 and 13 – You may notice that the overall GUI is slightly more attractive than those in previous posts. That’s because BoxLayouts (Lines 13, 18 and 29) are used on the rows and they offer different positioning options over GridLayouts and in the overall GUI padding and spacing are applied by both the GridLayout and BoxLayout to achieve the better look.
  • Line 14 – TextInput widget is placed in row 1 of GUI.
  • Line 15 – TextInput is id’d as entry. It’s from entry’s text property that Python ultimately gets the button text. (Line 36)
  • Line 17 – multiline is a method of TextInput. This sets a text entry to a single line.
  • Line 19 – spacing is set to 10 for the BoxLayout. Spacing is the amount of space between each button on the row .
  • Line 20 – on_press is a Kivy mouse release event. It calls my_button_text event handler class and sends it the entry.text property.
  • Line 42 – my_button_text function receives entry.text as my_text.
  • Line 43 – my_text is printed as a string to Pythons console output.

Simpler Version

A much simpler version of the above that avoids the TextInput window looks and works as follows,untitled-presentation-1

The complete working Kivy code is as follows;


import kivy
kivy.require("1.9.1") # used to alert user if this code is run on an earlier version of Kivy.
from kivy.app import App # imports Kivy App
from kivy.uix.gridlayout import GridLayout # imports GridLayout for use in app
from kivy.lang import Builder  # Imports the KV language builder that provides the layout of kivy screens

Builder.load_string(""" # KV Language string.
<ReadButtonTextGridLayout>: # Identifies layout/interactivity for the App.
    id: pad # ID's GridLayout as pad
    rows: 1 # Sets GridLayout row property to 1.
    GridLayout: # Row 1 layout
        rows: 3 # Sets GridLayout row property to 1.
        Button: # Creates a Buttin widget instance
            id: button1 # ID's Button as button 1
            text: "Hello, world!" # Text for above button.
            on_press:
                pad.my_buttons_text(button1.text)# on_press is a Kivy mouse release event.
        Button: # Creates a Buttin widget instance
            id: button2 # ID's Button as button 2
            text: "Hello, world! I'm here!" # Text for above button.
            on_press:
                pad.my_buttons_text(button2.text)# on_press is a Kivy mouse release event.
        Button: # Creates a Buttin widget instance
            id: button3 # ID's Button as button 3
            text: "Goodbye, world! I'm gone!" # Text for above button.
            on_press:
                pad.my_buttons_text(button3.text)# on_press is a Kivy mouse release event.
""")

class ReadButtonTextGridLayout(GridLayout): # Houses event handlers and directs a GridLayout for the <ReadButtonTextGridLayout> class.

    def my_buttons_text(self, my_text): # my_button_text event handler code
        print(str(my_text)) # my_text printed to Python console.

class ButtonReadingApp(App): # Creates the instance (copy) of the Kivy App class named ButtonReadingApp

    def build(self):# build is a method of Kivy's App class used to place widgets onto the GUI.
        return ReadButtonTextGridLayout() # return calls the build method which in turn builds the GUI.

ButtonReadingApp().run() # Runs ButtonReadingApp

Here are the changes to the code worth noting;

  • Line 14 – The first instance of the Button widget is given an id of button1
  • Line 17 – The buttons on_press event calls an event handler function called my_buttons_text and sends button1’s text property to the function.
  • Line 19 – The second instance of the Button widget is given an id of button2
  • Line 22 – The buttons on_press event calls an event handler function called my_buttons_text and sends button2’s text property to the function
  • Line 24 – The third instance of the Button widget is given an id of button3
  • Line 27 – The buttons on_press event calls an event handler function called my_buttons_text and sends button3’s text property to the function.
  • Line 32 – my_buttons_text function receives the buttons text property as my_text
  • Line 33 – Prints my_text string to the Python console.

Again my assumption here is that Python programmers will know what to do with any strings that come back from a Kivy interface such as adding them to a Python list (as in Part 15) or write code specific to their application based on the text that is returned from the GUI.

That wraps things up  for this blog post. The next blog post Kivy For The Non Computer Scientist – Part 17: Making Natural Looking GUI’s Using Kivy’s Float Layout. will focus on more natural looking Kivy GUI design.

Happy developing.

….brad….

Kivy For The Non Computer Scientist – Part 14: Button Presses That Update Labels And Change Screens Using KV Language.

This blog post combines the working code provided from Part 12 – KV Language – Switching Between Kivy GUI Screens and Part 13: Creating More Complex Kivy GUI’s Using Nesting And KV Language. The post also provides working code that not only switches between Kivy GUI screens but also demonstrates how Kivy Button widgets can update the text on Kivy Label widgets in real time.

A little bit on callbacks. When one clicks on a GUI button expecting something to happen, the process is technically called a callback. Most GUI languages I’ve used usually refer to a mouse click as an event. For the record, an event is actually a type of callback, so for this blogpost I’m going to refer to Button presses as an event.

For every event there are two parts to it;

  • There’s the event which is the code that makes an event happen.
    • such as defining a mouse click or a touch touchscreen
    • this is done using kv language.
  • There’s the event handler that defines via code what’s to happen once an event is initiated.
    • code might update a screen Label and/or go to another screen.
    • this is done using Python

You’ll see the code defined as events or event handlers in the comments of the working code provided in this blog post.

Here are the two screens that are active in the code provided;

untitled-presentation-1

Press the Appetizers Button To Access The Appetizer Screen

untitled-presentation-2

Press The Various Selection Buttons To Select Your Choice And Update The Selection Labels In Real Time.

The complete working code for this application is as follows;
import kivy  # Required to run Kivy such as the next line of code
kivy.require('1.9.1')  # used to alert user if this code is run on an earlier version of Kivy.
from kivy.app import App  # Imports the base App class required for Kivy Apps
from kivy.lang import Builder  # Imports the KV language builder that provides the layout of kivy screens
from kivy.uix.screenmanager import ScreenManager, Screen  # Imports the Kivy Screen manager and Kivys Screen class

Builder.load_string(""" # String that will build all four Kivy screens.
<WelcomeScreen>: # Identifies layout/interactivity for the WelcomeScreen.
    GridLayout: # Creates a GridLayout for WelcomeScreen.
        cols: 1 # Sets column property to 1.
        Label: # Creates a Label Widget instance.
            text: "You're On The Welcome Screen. Please Select Which Screen You Want To Go To" # Sets above Label text property
        Button: # Creates a Button Widget instance.
            text: 'Appetizers' #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event.
                root.manager.transition.direction = 'right' # Sets screen transition movement to right.
                root.manager.current = 'appetizer_screen' # Switches Kivy GUI screen to screen one.
        Button: # Creates a Button Widget instance.
            text: 'Switch To Screen Two' #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event.
                root.manager.transition.direction = 'right' # Sets screen transition movement to right.
                root.manager.current = 'screen_two' # Switches Kivy GUI screen to screen two.
        Button: # Creates a Button Widget instance.
            text: 'Switch To Screen Three' #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event.
                root.manager.transition.direction = 'right' # Sets screen transition movement to right.
                root.manager.current = 'screen_three' # Switches Kivy GUI screen to screen three.
<AppetizerScreen>: # Identifies layout/interactivity for the AppetizerScreen.
    GridLayout: # Creates a GridLayout for the entire appetizer GUI screen
        cols: 1 # Sets column property to 1.
        Label: # Creates a Label Widget instance for first row of GUI.
            text: 'Please Select Both A First And Second Appetizer' # Text for above Label.
        Label: # Creates a Label Widget instance for second row of GUI.
            text: 'First Appetizer Selection' # Text for above Label.
            id: first_app
            color: 1,1,1,1 # Sets text colour to black.
            canvas.before:
                Color: # Six lines of code (starting above) set Label background colour
                    rgba: 0.3, 0.3, 0.3,.6 # Colour code
                Rectangle:
                    pos: self.pos # required to position rectangle inside of Label widget.
                    size: self.size
        GridLayout: # Creates nested 2 column GridLayout on Row 3 of GUI.
            cols: 2 # Sets nested GridLayout to 2 columns.
            Label: # Creates a Label Widget in first column of nested GridLayout.
                text: 'Oysters On The Half' # Text for above Label.
            Button: # Creates a Button Widget in Second column of nested GridLayout.
                text: 'Please Select By Clicking Here' # Text for above Button.
                on_release:
                    # on_release is a Kivy mouse release event
                    root.oyster_selected() # Calls oyster_selected event handler class.
        Label: # Creates a Label Widget instance for fourth row of GUI.
            text: 'Or' # Text for above Label.
        GridLayout: # Creates nested 2 column GridLayout on Row 5 of GUI.
            cols: 2 # Sets nested GridLayout to 2 columns.
            Label: # Creates a Label Widget in first column of nested GridLayout.
                text: 'Smoked Pork Belly On Apple Butter\\nWith Baby Organic Kale Bourbon Glazed Pecans' # Text for above Label.
                halign: 'center' # Sets text horizontal alignment to cenre of button.
            Button: # Creates a Button Widget in Second column of nested GridLayout.
                text: 'Please Select By Clicking Here' # Text for above Button.
                on_release:
                    # on_release is a Kivy mouse release event
                    root.pork_belly_selected() # Calls pork_belly_selected event handler class.
        Label: # Creates a Label Widget instance for 6th row of GUI.
            text: 'Second Appetizer Selection' # Text for above Label.
            id: second_app
            canvas.before:
                Color: # Six lines of code (starting above) set Label background colour
                    rgba: 0.3, 0.3, 0.3,.6 # Colour code
                Rectangle:
                    pos: self.pos # required to position rectangle inside of Label widget.
                    size: self.size
        GridLayout: # Creates nested 2 column GridLayout on Row 7 of GUI.
            cols: 2 # Sets nested GridLayout to 2 columns.
            Label: # Creates a Label Widget in first column of nested GridLayout.
                text: 'Pan Seared Sea Scallop\\nCreamy Corn Grits With Sweet Pea Emulsion,\\nFried Crisp Leeks, Balsamic Drizzle' # Text for above Label.
                halign: 'center' # Sets text horizontal alignment to cenre of button.
            Button: # Creates a Button Widget in Second column of nested GridLayout.
                text: 'Please Select By Clicking Here' # Text for above Button.
                on_release:
                    # on_release is a Kivy mouse release event
                    root.scallop_selected() # Calls scallop_selected event handler class.
        Label: # Creates a Label Widget instance for 8th row of GUI.
            text: 'Or' # Text for above Label.
        GridLayout: # Creates nested 2 column GridLayout on Row 9 of GUI.
            cols: 2 # Sets nested GridLayout to 2 columns.
            Label: # Creates a Label Widget in first column of nested GridLayout.
                text: 'Craw Fish Bisque En Croute' # Text for above Label.
            Button: # Creates a Button Widget in Second column of nested GridLayout.
                text: 'Please Select By Clicking Here' # Text for above Button.
                on_release:
                    # on_release is a Kivy mouse release event
                    root.crawfish_selected() # Calls crawfish_selected event handler class.
        Button: # Creates a Button Widget instance on row 10 of GUI.
            text: "Return To Menu Welcome Screen By Clicking Here" #  Sets above button text property
            background_normal: "" # Button background defalts to grey. This sets the background to plain.
            background_color: (0.3, 0.3, 0.3,.6) # Sets Button background colour.
            on_release:
                # on_release is a Kivy mouse release event
                root.manager.transition.direction = 'right' # Sets screen transition movement to right.
                root.manager.current = 'welcome_screen' # Switches Kivy GUI screen to the welcome screen.
<SecondScreen>: # Identifies layout/interactivity for the SecondScreen.
    GridLayout: # Creates a GridLayout for SecondScreen.
        cols: 1 # Sets column property to 1.
        Button: # Creates a Button Widget instance.
            text: "You're On Screen Two. Press To Return To Welcome Screen" #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event
                root.manager.transition.direction = 'right' # Sets screen transition movement to right.
                root.manager.current = 'welcome_screen' # Switches Kivy GUI screen to the welcome screen.
<ThirdScreen>: # Identifies layout/interactivity for the ThirdScreen.
    GridLayout: # Creates a GridLayout for ThirdScreen.
        cols: 1 # Sets column property to 1.
        Button: # Creates a Button Widget instance.
            text: "You're On Screen Three. Press To Return To Welcome Screen" #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event
                root.manager.transition.direction = 'right' # Sets screen transition movement to right.
                root.manager.current = 'welcome_screen' # Switches Kivy GUI screen to the welcome screen.
""")

class WelcomeScreen(Screen):  # Creates a WelcomeScreen widget from the above kv language data string.
    pass  # Python placeholder for class.

class AppetizerScreen(Screen):  # Creates a AppetizerScreen widget from the above kv language data string.

    def oyster_selected(self): # Kivy event handler for events/callbacks on AppetizerScreen
        print("Oyster Selected") # Prints to python console.
        self.ids.first_app.text = "First Appetizer Selection: Oysters On The Half" # Code to update appetizer choice on Label id'd as first_app.

    def pork_belly_selected(self): # Kivy event handler for events/callbacks on AppetizerScreen
        print("Pork Belly Selected") # Prints to python console.
        self.ids.first_app.text = "First Appetizer Selection: Smoked Pork Belly On Apple Butter" # Code to update appetizer choice on Label id'd as first_app.

    def scallop_selected(self): # Kivy event handler for events/callbacks on AppetizerScreen
        print("Scallop Selected") # Prints to python console.
        self.ids.second_app.text = "Second Appetizer Selection: Pan Seared Sea Scallop" # Code to update appetizer choice on Label id'd as second_app.

    def crawfish_selected(self): # Kivy event handler for events/callbacks on AppetizerScreen
        print("Crawfish Selected") # Prints to python console.
        self.ids.second_app.text = "Second Appetizer Selection: Craw Fish Bisque En Croute" # Code to update appetizer choice on Label id'd as second_app.

class SecondScreen(Screen):  # Creates a SecondScreen widget from the above kv language data string.
    pass  # Python placeholder for class.

class ThirdScreen(Screen):  # Creates a ThirdScreen widget from the above kv language data string.
    pass  # Python placeholder for class.

sm = ScreenManager()  # Creates an instance (copy) of ScreenManager as variable sm. ScreenManager switches between Screen Objects.
sm.add_widget(WelcomeScreen(
    name='welcome_screen'))  # Adds WelcomeScreen widget to ScreenManager. ScreenManager id's screen as welcome_screen.
sm.add_widget(AppetizerScreen(
    name='appetizer_screen'))  # Adds AppetizerScreen widget to ScreenManager. ScreenManager id's screen as appetizer_screen.
sm.add_widget(SecondScreen(
    name='screen_two'))  # Adds SecondScreen widget to ScreenManager. ScreenManager id's screen as screen_two.
sm.add_widget(ThirdScreen(
    name='screen_three'))  # Adds ThirdScreen widget to ScreenManager. ScreenManager id's screen as screen_three.

class SwitchingScreenApp(App):  # Creates the instance (copy) of the Kivy App class named SwitchingScreenApp

    def build(self):  # build is a method of Kivy's App class used to place widgets onto the GUI.
        return sm  # return calls the build method which in turn builds the GUI.

SwitchingScreenApp().run()  # Runs SwitchingScreenApp

Ok, where’s the code and the code changes that make this all work?

  • Line 31 – from Part 12 changed to so the screen containing the appetizer code could be identified in the kv language code more clearly.
  • Line 32 – Appetizer screen code from Part 13 replaces code from this line on.
    • Line 18 – code changed from screen_one to appetizer_screen for Screen Manager switching.
  • Line 38 – Label is given an id of first_app. This identification will be used later to update Labels text when a specific appetizer is selected.
  • Line 52 – Kivy on_release event added to Oyster selection Button.
  • Line 54 – Event handler called using root.oyster_selected().
    • oyster_selected() is defined as Python function in the AppetizerScreen class starting on Line 130.
  • Line 64 – Kivy on_release event added to Pork Belly selection Button.
  • Line 66 – Event handler called using root.pork_belly_selected().
    • pork_belly_selected() is defined as Python function in the AppetizerScreen class starting on Line 130.
  • Line 69 – Label is given an id of second_app. This identification will be used later to update Labels text when a specific appetizer is selected.
  • Line 83 – Kivy on_release event added to Scallop selection Button.
  • Line 85 – Event handler called using root.scallop_selected().
    • scallop_selected() is defined as Python function in the AppetizerScreen class starting on Line 130
  • Line 83 – Kivy on_release event added to Crawfish selection Button.
  • Line 85 – Event handler called using root.crawfish_selected().
    • crawfish_selected() is defined as Python function in the AppetizerScreen class starting on Line 130
  • Lines 103 and 104 – Screen manager code event code inserted so screen will switch back to when selected.
  • Line 130 – Appetizer screen class code. Note all python code required for this screen are defined as functions within this class.
  • Line 132 – oyster_selection() function defined.
  • Line 133 – Oyster Selected is printed to Python console using standard Python 3 code.
  • Line 134 – self.ids.first_app.text is used to update the Label id’d as first_app to Oyster selection.
  • Line 136 – pork_belly_selection() function defined.
  • Line 137 – Pork Belly Selected is printed to Python console using standard Python 3 code.
  • Line 138 – self.ids.first_app.text is used to update the Label id’d as first_app to Pork Belly selection.
  • Line 140 – scallop_selection() function defined.
  • Line 141 – Scallop Selected is printed to Python console using standard Python 3 code.
  • Line 142 – self.ids.second_app.text is used to update the Label id’d as second_app to Scallop selection.
  • Line 144 – crawfish_selection() function defined.
  • Line 145 – Craw Fish Selected is printed to Python console using standard Python 3 code.
  • Line 146 – self.ids.second_app.text is used to update the Label id’d as second_app to Crawfish selection.
  • Line 156 – is identified to Screen Manager as appetizer_screen.

To this point in these series of posts we’ve walked through and provided complete working code that provides basic widgets, provides event code to both switch screens and update labels through pushing buttons. There’s even a little bit of code that interacts directly with Python by printing output to its console.

Our next post will provide a little more code that will make it clearer how to manipulate information obtained from the GUI using the standard Python language. You can find it at Kivy For The Non Computer Scientist – Part 15: Interacting With Python

….brad….