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….

Advertisements

3 Responses

  1. […] That pretty much wraps this blog post. Next post we’ll add some interactivity to this code that will allow one to make appetizer selections by clicking the Kivy buttons and seeing the results in the GUI. That post can be found at Kivy For The Non Computer Scientist – Part 14: Button Presses That Update Labels And Change Screen…. […]

  2. […] form a fixed price menu. This will be done by completing the menu screens from the code provided in Kivy For The Non Computer Scientist – Part 14: Button Presses That Update Labels And Change Screen… and having the selections stored in a Python list. My assumption is that once the customers order […]

  3. Very Nice Blog. Check out mine too!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: