Kivy For The Non Computer Scientist – Part 15: Interacting With Python

To date in this series of blog posts I have pretty much focused on Kivy, KV Language and making a Kivy Gui work. However Kivy is not a GUI unto itself. Eventually we want the GUI to overlay and provide control over Python code that makes up our particular application.

In this blog post I will provide complete working Kivy/Python code for an app that collects a customers order 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 Screens Using KV Language and having the selections stored in a Python list. My assumption is that once the customers order is stored in a list you, as a Python programmer, can write additional code based on that Python list to do whatever you want with the order information.

The Python list will be titled  final_selection_list and will contains the four elements that make up the customers order;

  • final_selection_list[0] will be Appetizer 1 selection.
  • final_selection_list[1] will be Appetizer 2 selection.
  • final_selection_list[2] will be the Main meal selection.
  • final_selection_list[3] will be Dessert selection.

The list will output to the Python console in real time as selections are made and changed. Once again the GUI’s will not be all that attractive in order to minimize the working code for better understanding. The new/updated screens will appear in this app as follows;

welcome

Welcome Menu Screen

main_course

Main Course Menu Screen

dessert

Dessert Menu Screen

untitled-presentation-3

As You Select And Change Items A Python List Will Be Generated And Displayed In Console In Real Time When You Run The Provided Code

Here is the complete working code for this app including the Appetizer screen that was coded in the last two blogposts;


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

final_selection_list = ["-","-","-","-"]

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: "Welcome To Roux Resturant\\nPlease Select Your Order For Tonights Fixed Price Dinner" # Sets above Label text property
            halign: 'center' # Sets text horizontal alignment to cenre of button.
        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: 'Mains' #  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 = 'mains_screen' # Switches Kivy GUI screen to screen two.
        Button: # Creates a Button Widget instance.
            text: 'Dessert' #  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 = 'dessert_screen' # 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 # Identifies Label as first_app. id will be used to update label text as selections are made.
            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 # Identifies Label as second_app. id will be used to update label text as selections are made.
            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 Main Menu 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.
<MainsScreen>: # Identifies layout/interactivity for the MainsScreen.
    GridLayout: # Creates a GridLayout for the entire mains GUI screen
        cols: 1 # Sets column property to 1.
        Label: # Creates a Label Widget instance for first row of GUI.
            text: 'Please Select Your Main Course By Clicking On It' # Text for above Label.
            id: mains # Identifies Label as mains. id will be used to update label text as selections are made.
        Button: # Creates a Button Widget instance.
            text: "Oven Roasted Chicken Breast" #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event
                root.chicken_selected() # Calls chicken_selected event handler class.
        Label: # Creates a Label Widget instance..
            text: 'Or' # Text for above Label.
        Button: # Creates a Button Widget instance.
            text: "Arctic Char" #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event
                root.char_selected() # Calls char_selected event handler class.
        Label: # Creates a Label Widget instance..
            text: 'Or' # Text for above Label.
        Button: # Creates a Button Widget instance.
            text: "Beef Tenderloin" #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event
                root.beef_selected() # Calls beef_selected event handler class.
        Label: # Creates a Label Widget instance.
            text: 'Or' # Text for above Label.
        Button: # Creates a Button Widget instance.
            text: "Potato Cannelloni" #  Sets above button text property
            on_release:
                # on_release is a Kivy mouse release event
                root.cannelloni_selected() # Calls cannelloni_selected event handler class.
        Label: # Creates a Label Widget instance..
            text: 'And' # Text for above Label.
        Button: # Creates a Button Widget instance.
            text: "Return To Main Menu Screen By Clicking Here" #  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.
<DessertScreen>: # Identifies layout/interactivity for the DessertScreen.
    GridLayout: # Creates a GridLayout for the entire dessert GUI screen
        cols: 1 # Sets column property to 1.
        Label: # Creates a Label Widget instance for first row of GUI.
            text: 'Please Select Your Dessert Choice By Clicking On It' # Text for above Label.
            id: dessert # Identifies Label as dessert. id will be used to update label text as selections are made.
        Button: # Creates a Button Widget instance.
            text: "Apple Crumble Panna Cotta\\nChocolate Sauce &amp;amp; Crumb Crust" #  Sets above button text property
            halign: 'center' # Sets text horizontal alignment to cenre of button.
            on_release:
                # on_release is a Kivy mouse release event
                root.crumble_selected() # Calls crumble_selected event handler class.
        Label: # Creates a Label Widget instance..
            text: 'Or' # Text for above Label.
        Button: # Creates a Button Widget instance.
            text: "Beignets &amp;amp; Brulee\\nWarm House Beignets &amp;amp; Creme Brulee" #  Sets above button text property
            halign: 'center' # Sets text horizontal alignment to cenre of button.
            on_release:
                # on_release is a Kivy mouse release event
                root.beignets_selected() # Calls beignets_selected event handler class.
        Label: # Creates a Label Widget instance..
            text: 'And' # Text for above Label.
        Button: # Creates a Button Widget instance.
            text: "Return To Main Menu Screen By Clicking Here" #  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.
        final_selection_list.pop(0) # Deletes list element 0
        final_selection_list.insert(0,"Oysters On The Half") # Inserts food choice in list element 0
        print(final_selection_list) # Prints final_selection_list to console

    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.
        final_selection_list.pop(0) # Deletes list element 0
        final_selection_list.insert(0, "Smoked Pork Belly On Apple Butter") # Inserts food choice in list element 0
        print(final_selection_list) # Prints final_selection_list to console

    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.
        final_selection_list.pop(1) # Deletes list element 1
        final_selection_list.insert(1, "Pan Seared Sea Scallop") # Inserts food choice in list element 1
        print(final_selection_list) # Prints final_selection_list to console

    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.
        final_selection_list.pop(1) # Deletes list element 1
        final_selection_list.insert(1, "Craw Fish Bisque En Croute") # Inserts food choice in list element 1
        print(final_selection_list) # Prints final_selection_list to console

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

    def chicken_selected(self): # Python event handler for events/callbacks on MainsScreen
        print("Crawfish Selected") # Prints to python console.
        final_selection_list.pop(2) # Deletes list element 2
        final_selection_list.insert(2, "Oven Roasted Chicken Breast") # Inserts food choice in list element 2
        self.ids.mains.text = "Main Course Selected: Oven Roasted Chicken Breast" # Updates Label id: mains text indicating selection to user.
        print(final_selection_list) # Prints final_selection_list to console

    def char_selected(self): # Python event handler for events/callbacks on MainsScreen
        print("Arctic Char Selected")  # Prints to python console.
        final_selection_list.pop(2) # Deletes list element 2
        final_selection_list.insert(2, "Arctic Char") # Inserts food choice in list element 2
        self.ids.mains.text = "Main Course Selected: Arctic Char" # Updates Label id: mains text indicating selection to user.
        print(final_selection_list) # Prints final_selection_list to console

    def beef_selected(self): # Python event handler for events/callbacks on MainsScreen
        print("Beef Tenderloin Selected")  # Prints to python console.
        final_selection_list.pop(2) # Deletes list element 2
        final_selection_list.insert(2, "Beef Tenderloin") # Inserts food choice in list element 2
        self.ids.mains.text = "Main Course Selected: Beef Tenderloin" # Updates Label id: mains text indicating selection to user.
        print(final_selection_list) # Prints final_selection_list to console

    def cannelloni_selected(self): # Python event handler for events/callbacks on MainsScreen
        print("Potato Cannelloni Selected")  # Prints to python console.
        final_selection_list.pop(2) # Deletes list element 2
        final_selection_list.insert(2, "Potato Cannelloni") # Inserts food choice in list element 2
        self.ids.mains.text = "Main Course Selected: Potato Cannelloni" # Updates Label id: mains text indicating selection to user.
        print(final_selection_list) # Prints final_selection_list to console

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

    def crumble_selected(self): # Python event handler for events/callbacks on DessertScreen
        print("Apple Crumble Selected")  # Prints to python console.
        final_selection_list.pop(3) # Deletes list element 3
        final_selection_list.insert(3, "Apple Crumble Panna Cotta") # Inserts food choice in list element 3
        self.ids.dessert.text = "Dessert Selected: Apple Crumble Panna Cotta" # Updates Label id: dessert text indicating selection to user.
        print(final_selection_list) # Prints final_selection_list to console

    def beignets_selected(self): # Python event handler for events/callbacks on DessertScreen
        print("Beignets &amp;amp; Brulee Selected")  # Prints to python console.
        final_selection_list.pop(3) # Deletes list element 3
        final_selection_list.insert(3, "Beignets &amp;amp; Brulee") # Inserts food choice in list element 3
        self.ids.dessert.text = "Dessert Selected: Beignets &amp;amp; Brulee" # Updates Label id: dessert text indicating selection to user.
        print(final_selection_list) # Prints final_selection_list to console

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(MainsScreen(
    name='mains_screen'))  # Adds MainsScreen widget to ScreenManager. ScreenManager id's screen as mains_screen.
sm.add_widget(DessertScreen(
    name='dessert_screen'))  # Adds DessertScreen widget to ScreenManager. ScreenManager id's screen as dessert_screen.

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

    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.

FixedPriceMenuApp().run()  # Runs FixedPriceMenuApp

In this code review I’m just going to focus on the code that builds the Python list. The code that built the Mains and Dessert screens were and provided the GUI interactivity were covered in Parts 13 and 14 of this blog series and the relevant code was duplicated where it was applied in creating the additional screens.

That said the new code that builds the Python list is as follows;

  • Line 7 – final_selection_list is initialized using hyphens as placeholders.
  • Line 186 – Code deletes final_selection_list[0] element
  • Line 187 – Code inserts new food item (in this case Oyster info) in deleted list element location
  • Line 188 – final_selection_list is printed to Python console providing real-time update
  • Lines 193 thru 195 – Same code as Lines 186 thru 189 except for Pork Belly selection and final_selection_list[1] element.
  • Lines 200 thru 202 – Same code as Lines 186 thru 189 except for Scallop selection and final_selection_list[1] element.
  • Lines 207 thru 209 – Same code as Lines 186 thru 189 except for Crawfish selection and final_selection_list[1] element.
  • Lines 216 thru 218 – Same code as Lines 186 thru 189 except for Chicken selection and final_selection_list[2] element.
  • Lines 223 thru 225 – Same code as Lines 186 thru 189 except for Char selection and final_selection_list[2] element.
  • Lines 230 thru 232 – Same code as Lines 186 thru 189 except for Beef selection and final_selection_list[2] element.
  • Lines 237 thru 239 – Same code as Lines 186 thru 189 except for Cannelloni selection and final_selection_list[2] element.
  • Lines 246 thru 248 – Same code as Lines 186 thru 189 except for Crumble selection and final_selection_list[3] element.
  • Lines 253 thru 255 – Same code as Lines 186 thru 189 except for Beignets selection and final_selection_list[3] element.

With this post I wrap what I wanted to accomplish within this series of blog post. I have posted several simple and complete Kivy code sets with comments that brings one from Kivy’s Hello, world! app right through to an app that has full screen switching, interaction and updating on Kivy GUI’s and interacts with Python by collecting user information into a traditional Python list.

With these basics I’m confident that one can move forward quickly in developing more attractive GUI’s and then develop write once cross platform applications that will work on IOS, Android, MacOS, Windows and Linux  –including Raspberry Pi’s–.

Happy developing and please if you learn new things especially relating to Kivy, share them on the internet so others can learn. Happy developing…..

Here’s the link to the next instalment in this blog post series, Kivy For The Non Computer Scientist – Part 16: Reading Text From Kivy Buttons For Python Code Manipulation Created In KV Language.

Cheers

….brad….

Advertisements

3 Responses

  1. […] 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 […]

  2. […] 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 […]

  3. http://wp.me/p7UB6x-kB

    see that one.

    btw your blog 👌

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: