Kivy For The Non Computer Scientist – Part 13: Creating More Complex Kivy GUI’s Using Nesting And KV Language

As mentioned in Kivy For The Non Computer Scientist – Part 2: Concepts To Get A Handle On, the second blog post in this series, I mentioned one of key Kivy concepts is that complex Kivy GUI’s are created by nesting. Nesting means placing widgets within widgets or layouts within layouts. Once the ‘penny drops” for you on this concept, you’ll immediately see how more complex interfaces –meaning many buttons and widgets arranged on the screen– can be created.

Lets start by considering the following Kivy GUI;

complex

Admittedly this is not a visually appealing GUI, but it’ll serve well to first teach the fundamentals of kv language nested layouts and later widget interactivity in more complex GUI’s. (BTW – Nicer looking Kivy GUI’s are created by replacing things like a buttons canvas with images. But in order to keep the code examples simple, using images as buttons/backgrounds etc. can be covered in a future blog post.)

The GUI itself is made up of 10 rows. Some rows are comprised of one column being either a Label Widget or a Button Widget. Other rows are comprised of two columns, one column being a Label Widget that contains the type of appetizer and the second column being a button so a user can select their choice.

While there are several ways one could approach this layout using Kivy, in this example this layout is achieved by nesting GridLayouts within GridLayouts and assigning the appropriate Label and Button widgets accordingly. Here is the complete code for this layout with comments but no interactivity;


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

kivyscreen = Builder.load_string(""" # The variable kivyscreen is assigned the string that will build Kivy screen
GridLayout: # Creates a GridLayout for the entire GUI
    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.
        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.
    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.
    Label: # Creates a Label Widget instance for 6th row of GUI.
        text: 'Second Appetizer Selection' # Text for above Label.
        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.
    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.
    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.
            pass  # Python placeholder for class.
""")  # End of string.

class NestedButtonsApp(App):  # Creates the instance (copy) of the Kivy App class named NestedButtonApp.
    def build(self):  # build is a method of Kivy's App class used to place widgets onto the GUI.
        return kivyscreen  # return calls the build method which in turn builds the GUI.

NestedButtonsApp().run()  # Calls the NestedButtonApp object to run the app.

So what’s new and notable in this code….

  • Line 20 – This is the first instance of nesting layouts in the code. To this point in this blog series we would have normally placed either a Button or Label widget at this spot. Instead a GridLayout was used which placed a nested GridLayout on row 3 of the Kivy GUI. This GridLayout is set to two columns on line 21 allowing both a Label and Button to be placed on row 3 of the Kivy GUI.
    • The code for this nested layout is indented an additional level from our first GridLayout which was called on line 7 of the code. It’s the indentation style that allows for nesting layouts in kv language.
  • Line 31 – \\n placed in the text string creates a linebreak when the text is placed on Kivy’s screen.
  • Line 32 – When a linebreak is used in a text string, it breaks KIvy’s default centring of text  on this widget. Hence the halign: ‘center’ code is used to realign the text horizontally back to a centred orientation.
  • Line 39 – In Kivy For The Non Computer Scientist – Part 11: Using KV Language To Set Widget Text Size, Text Position And Text And Button Colours, I covered the canvas.before code. It’s purpose is to change the background colour of a Label. The code here is set in decimal numbers where previously I had used whole numbers.
    • Using decimals allows one to set shades of colours by altering the first three numbers using decimal points. 1 is the maximum number you can use in an rgba setting.
    • The fourth number is luminance. By adjusting it you can make the overall background colour lighter or darker.

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 Screens Using KV Language.

Happy New Year,

….brad….

Advertisements

3 Responses

  1. […] posts we’ll need to take a look at nested screens and further Kivy interaction with Python. Kivy For The Non Computer Scientist – Part 13: Creating More Complex Kivy GUI’s Using Nesting An… is the next post in this […]

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

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

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: