Kivy For The Non Computer Scientist – Part 9: Dynamic Checkbox Labels

If you’ve been following this series of Kivy blog posts this may be where you want to review what I did to make the checkbox dynamic and then review and try the code on the official Kivy CheckBox page as they differ.

My code below builds upon the code shown in Part 8 of this blog series and the widgets on_press method to call a standard Python function. That function makes the checkbox dynamic by changing the feedback_label’s text to “Hello, world!” when checked and “Goodbye, world!” when unchecked. Since Kivy runs in a continuous loop on can check and uncheck the check box as much as they want and the feedback_label text will change dynamically.

The code to make the checkbox dynamic is as follows;

dynamic


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.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.checkbox import CheckBox # Imports the Check Box Screen Widget for use in the app.
class ThreeColumnApp(App): # Creates the instance (copy) of the Kivy App class named ThreeColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout(cols = 3) # Sets grid layout and the number of columns to 3 as the my_layout instance is created.
        self.my_check_box = CheckBox(on_press = self.hello_world) # Creates a Check Box instance and sets its text property to I'm A Button. Press Me.
        self.my_check_box_label = Label(text="Please Check Me") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        self.my_feedback_label = Label(text="I'm Your Feedback Label") # Creates a Label Widget instance and sets its text property to Im Your Feedback Label.
        my_layout.add_widget(self.my_check_box) # Adds the check box widget to my_layout
        my_layout.add_widget(self.my_check_box_label) # Adds the label widget to My_layout
        my_layout.add_widget(self.my_feedback_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
    def hello_world(self,event): # Creates the hello_world function to be used by checkbox as its event.
        if self.my_feedback_label.text != "Hello, world!": # Tests to see if Hello, world is current label text.
        self.my_feedback_label.text = "Hello, world!" # Sets the GUIs label text property to Hello, world!.
    else:
        self.my_feedback_label.text = "Goodbye, world!" # Sets the GUIs label text property to Goodbye, world!.
ThreeColumnApp().run() # Calls the ThreeColumnApp object to run the app.

  • Lines 17 thru 21 – The only change to this code from Part 8 is in the hello_world function where a Python if … else statement has been written. Simply put the If statement determines if the feedback_labels text is “Hello, world!” when called. If it is “Hello, world!” the function changes the feedback_labels text to “Goodbye, world!”.
    • If the function finds the feedback_label not equal to “Hello, world!” it changes it to “Hello, world!” which is great for the first check and all subsequent checks to the checkbox.

Again, I invite you to look at the method associated with the CheckBox widget found in Kivy’s documentation. Its different in that the method issues a boolean when the checkbox is clicked. I simply struggled in getting it to work because the page did not provide a full working version of its code.

I like the the code I provided above because it allows me to write Python code in the manner I’m used to and via a function one check can be programmed to do many things. We’ve now learned to dynamicize Kivy’s buttons and checkboxes in 22 lines of Python code. And the fact that we can now trigger our code with either a checkbox of a button and dynamically update our screen we now have the basics we need to produce apps employing a Kivy GUI.

Here is the link to Kivy For The Non Computer Scientist – Part 10: KV Language the next post in this series.

….brad….

Kivy For The Non Computer Scientist – Part 8: Adding A Checkbox Label

Unfortunately with Kivy the Checkbox screen widget (at the time of writing) does not come with a text property that would create a checkbox label. Since advanced layouts at this point in my Kivy experience remain a bit of a mystery, I came up with a solution by adding a third column that would be used as a label for the checkbox.

The code is as follows;

check

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.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.checkbox import CheckBox # Imports the Check Box Screen Widget for use in the app.
class ThreeColumnApp(App): # Creates the instance (copy) of the Kivy App class named ThreeColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout(cols = 3) # Sets grid layout and the number of columns to 3 as the my_layout instance is created.
        self.my_check_box = CheckBox(on_press = self.hello_world) # Creates a Check Box instance and sets its text property to I'm A Button. Press Me.
        self.my_check_box_label = Label(text="Please Check Me") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        self.my_feedback_label = Label(text="I'm Your Feedback Label") # Creates a Label Widget instance and sets its text property to Im Your Feedback Label.
        my_layout.add_widget(self.my_check_box) # Adds the check box widget to my_layout
        my_layout.add_widget(self.my_check_box_label) # Adds the label widget to My_layout
        my_layout.add_widget(self.my_feedback_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
    def hello_world(self,event): # Creates the hello_world function to be used by checkbox as its event.
        self.my_feedback_label.text = "Hello, world!" # Sets the GUIs feedback_label text property to Hello, world! when function is called.
ThreeColumnApp().run() # Calls the ThreeColumnApp object to run the app.

The code has a few changes in it from that used in Part 7 of this blog series but no new concepts were introduced with this code;

  • Line 9 sets this app up as a 3 column layout.
    • The class name (Line 7) is changed to reflect its three column design.
  • Lines 10, 11 and 12 establish instances of the three screen widgets for use in the app.
    • Line 11 is the additional label widget that’s used as the checkbox label.
    • Line 12 is identified as the feedback label that will change when the checkbox is clicked
  • Line 18 changes the feedback text when the hello_world function is called.

While the interface isn’t pretty at this point but it is at least functional using 19 lines of code. You should by now have a pretty good handle on what each line of code does. My next post will add a couple of lines of code that will update the screen when the checkbox is checked or  unchecked.

….brad….

Here is the link to the next post in this blog series: Kivy For The Non Computer Scientist – Part 9: Dynamic Checkbox Labels

Kivy For The Non Computer Scientist – Part 7: Simple Checkbox Code

By now (hopefully) you are gaining some confidence with Python code that incorporates Kivy. The code below integrates a simple Check Box that when “checked” changes the label to “Hello, world!”

checkbox

Here is the editable source,


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.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.checkbox import CheckBox # Imports the Check Box Screen Widget for use in the app.
class TwoColumnApp(App): # Creates the instance (copy) of the Kivy App class named TwoColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout(cols = 2) # Sets grid layout and the number of columns to my_layout as the instance is created. One less line of code.
        self.my_first_check_box = CheckBox(on_press = self.hello_world) # Creates a Check Box instance and sets its text property to I'm A Button. Press Me.
        self.my_first_label = Label(text="Please Check Me") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        my_layout.add_widget(self.my_first_check_box) # Adds the check box widget to my_layout
        my_layout.add_widget(self.my_first_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
    def hello_world(self,event): # Creates the hello_world function to be used by checkbox as its event.
        self.my_first_label.text = "Hello, world!" # Sets the GUIs label text property to Hello, world! when function is called.
TwoColumnApp().run() # Calls the TwoColumnApp object to run the app.

So What’s Different?

From the button code introduced in Part 6 of this blog series the changes are as follows,

  • Line 6 imports the Check Box screen widget for use in the app.
  • Line 10 creates a Check Box instance titled self.my_first_check_box. Check Box still has the on_press method that calls the hello_world function as part of its code base but it differs from a Button because it does not have a text property.
  • Line 12 adds the self.my_first_check_box Check Box to my_layout.

Now that we have the label working, this application begs two more questions;

  1. How do I label a Check Box?
  2. How do I make an action occur when the Check Box is not “clicked”?

We will look into these questions in the next two posts.

….brad….

Here is the link to the next post in this series: Kivy For The Non Computer Scientist – Part 8: Adding A Checkbox Label

Kivy For The Non Computer Scientist – Part 6: Code Cleanup And Kivy Convention.

Before moving on I’d be remiss if I didn’t create a short post and update the code from Part 5 of this blog post series to make it more Pythonic and to conform to Kivy convention(s). Here is the updated code;


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.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.button import Button # Imports the Button Screen Widget for use in the app.
class TwoColumnApp(App): # Creates the instance (copy) of the Kivy App class named TwoColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout(cols = 2) # Sets grid layout and the number of columns to my_layout as the instance is created. One less line of code.
        self.my_first_button = Button(text="I'm A Button. Press Me", on_press = self.hello_world) # Creates a Button Widget instance and sets its text property to I'm A Button. Press Me.
        self.my_first_label = Label(text="Please Press My Button") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        my_layout.add_widget(self.my_first_button) # Adds the button widget to my_layout
        my_layout.add_widget(self.my_first_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
    def hello_world(self,event): # Creates the hello_world function to be used by button as its event.
        self.my_first_label.text = "Hello, world!" # Sets the GUIs label text property to Hello, world! when function is called.
TwoColumnApp().run() # Calls the TwoColumnApp object to run the app.

What’s Added?

Line 1 – Up to this point in our code creation we have only used widgets associated with Kivy’s App class. However in order to use other elements of Kivy, such as .kv language or in this case Kivy’s version requirement method on Line 2, one starts with the import kivy statement kivy because it loads Kivy’s framework.

Line 2 is code that uses Kivy’s framework to check the minimum version required to run this Kivy application. The programmer sets it to the Kivy version on which the code is written. If a user attempts to run your application with a version of Kivy that is older than the specified version, an Exception is raised.

Line 9 concatenates what was two lines of code into one by setting my_layout’s column count by setting it using GridLayout’s brackets.

Next In The Series

Since the learning goal of this series was to build a button, switch and checkbox interface, the next blog post will focus on the checkbox.

….brad….

Next post in this blog series: Kivy For The Non Computer Scientist – Part 7: Simple Checkbox Code

Kivy For The Non Computer Scientist – Part 5: Making A Kivy Button Do Something

As stated in Part 2 the goal of this blog series is to produce a simple button, switch and checkbox interface with very simple and complete code examples. While Part 3 provided the background and code related to Kivys Object Oriented Programming (OOP) principles required by Kivy and Part 4 provided the code on simple screen layouts, this blog entry will build upon the code from Part 4 by providing the code to change the text fn the label on the GUI to Hello. world! by mouse clicking or touching the button. The complete code to accomplish this is as follows;

pressgui

The code is as follows (from Part 4 with Button Event code added);


from kivy.app import App # Imports the base App class required for Kivy Apps
from kivy.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.button import Button # Imports the Button Screen Widget for use in the app.
class TwoColumnApp(App): # Creates the instance (copy) of the Kivy App class named TwoColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout() # Creates a GridLayout titled my_layout for use in the app.
        my_layout.cols = 2 # Sets my_layout column property to 2
        self.my_first_button = Button(text="I'm A Button. Press Me", on_press = self.hello_world) # Creates a Button Widget instance and sets its text property to I'm A Button. Press Me.
        self.my_first_label = Label(text="Please Press My Button") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        my_layout.add_widget(self.my_first_button) # Adds the button widget to my_layout
        my_layout.add_widget(self.my_first_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
    def hello_world(self,event):
        self.my_first_label.text = "Hello, world!"
TwoColumnApp().run() # Calls the TwoColumnApp object to run the app.

So Where Is The Code That Makes The Kivy Button Trigger An Event?

The additional code to create the button event is as follows;

  • On Lines 14 and 15 an event function is named and its action defined.
    • Line 14 names the function hello_world.
    • Line 15 instructs the self.my_first_label to change its text to Hello, world!
  • Line 9 adds on_press = self.hello_world to the self.my_first_button code.
    • It is the buttons on_press behavior method that calls an event. In this case it is set to self.hello_world which calls the hello_world function. As shown above the hello_world function changes Kivy’s Label Widget text to Hello, world!.

Here is the final code for Part 5 with each line commented explaining what it does;


from kivy.app import App # Imports the base App class required for Kivy Apps
from kivy.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.button import Button # Imports the Button Screen Widget for use in the app.
class TwoColumnApp(App): # Creates the instance (copy) of the Kivy App class named TwoColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout() # Creates a GridLayout titled my_layout for use in the app.
        my_layout.cols = 2 # Sets my_layout column property to 2
        self.my_first_button = Button(text="I'm A Button. Press Me", on_press = self.hello_world) # Creates a Button Widget instance and sets its text property to I'm A Button. Press Me.
        self.my_first_label = Label(text="Please Press My Button") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        my_layout.add_widget(self.my_first_button) # Adds the button widget to my_layout
        my_layout.add_widget(self.my_first_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
    def hello_world(self,event): # Creates the hello_world function to be used by button as its event.
        self.my_first_label.text = "Hello, world!" # Sets the GUIs label text property to Hello, world! when function is called.
TwoColumnApp().run() # Calls the TwoColumnApp object to run the app.

With these first five blogposts you should now be on your way to start creating your own KIVY interface. You now know the basics of how Kivy’s OOP, screen layouts, screen widgets and button event handling works. You now have a simple straightforward code base (only 16 lines of code) that will help you get started on your own Kivy GUI that uses button and label widgets.

….brad….

Link to the next blog post in this series: Kivy For The Non Computer Scientist – Part 6: Code Cleanup And Kivy Convention.

Kivy For The Non Computer Scientist – Part 4: A Little About Kivy’s Screen Layouts

Everything I’ve covered to this point in this series of blog posts relating to Kivy has been well covered by other Kivy community members and educators. But as I traveled down my learning path of Kivy over the past few weeks, other than my weak understanding of OOP principles, it was when I hit screen layouts I got stymied for a while.

The reason was because just about every resource I came across provided too much information (TMI) on how the eight different screen layout classes arranged widgets and how widget properties are employed to size and proportion said widgets on the screen. The experience was mind-numbing. To my way of thinking it’s best to start with one screen layout object, first learn how to invoke it and then at a later date learn more about its properties and characteristics and proceed with confidence. That’s why I titled this post “A Little About Kivy’s Screen Layouts”.

For the purposes of this blog post and the code associated with it we are going to use Kivy’s GridLayout. As mentioned earlier screen layout objects are used to position widgets on Kivy’s GUI and a grid layout is probably the easiest to understand.

gridlayout

The image above from kiby.org demonstrates how Kivy’s GridLayout works. By setting the maximum amount of widgets you want arranged by either rows or columns, the screen widgets are automatically assigned a position determined by the layout configuration.

maxresdefault

Recall Matt Richardson’s Kivy interface (above) that was shown in Part 1 of this blog. If  I wanted to duplicate it, I would start with a Grid Layout and set the value of its col property to five. By adding an image widget, three button widgets and one slider widget (in that order) the widgets would arrange themselves in their appropriate columns into the grid layout as it appears above. Note that Screen Widgets get added to a Kivy GridLayout from left to right.

Lets Get To The Code!

To keep thing really simple were going to start with only two columns on our grid layout. The Python code below creates a two column Kivy grid screen layout onto which two screen widgets appear. One being a Button Widget and the second being a Label Widget;

gridlayout

Below is the source code;

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
class TwoColumnApp(App):
    def build(self):
        my_layout = GridLayout()
        my_layout.cols = 2
        self.my_first_button = Button(text="I'm A Button. Press Me")
        self.my_first_label = Label(text="Please Press My Button")
        my_layout.add_widget(self.my_first_button)
        my_layout.add_widget(self.my_first_label)
        return my_layout
TwoColumnApp().run()

Review

This source code and how it works builds upon the previous examination of kivy.orgs “Hello World” code in Part 3 of this blog series. So lets start by reviewing parts of the code that we already know from that review;

  • Line 1 of the code imports the Kivy’s App class for use in this App. This is Kivy’s underlying code that creates the base GUI and is a requirement for most Kivy applications.
  • Line 5 of the code creates the instance –technically computer scientists call this a subclass– of Kivy’s App class and names the object “TwoColumnApp”.
  • Line 4 of the code imports Kivy’s Button Widget for use in the app.
  • Line 9 of the code creates an instance of Kivy’s Button Widget with the buttons text property set to “I’m A Button. Press Me”.
  • Line 6 references the build method. build is a method of Kivy’s App class and was inherited by the TwoColumnApp object when it was created. build is an object that simply places screen widgets on the GUI when called.
  • Line 6 uses the keyword “self” and simply put it refers to “the current Kivy widget instance”
  • Line 13 starts with the command return. When the program is run, return calls the build method which in turn builds and displays the GUI.
  • Line 14 calls the TwoColumnApp object to run. The Kivy app runs in a continuous loop until terminated.

Hence the code below is commented line by line with what we’ve learned to date;


from kivy.app import App # Imports the base App class required for Kivy Apps
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button # Imports the Button Screen Widget
class TwoColumnApp(App): # Creates the instance (copy) of the Kivy App class named TwoColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout()
        my_layout.cols = 2
        self.my_first_button = Button(text="I'm A Button. Press Me") # Creates a Button Widget instance and sets its text property to Im A Button. Press Me.
        self.my_first_label = Label(text="Please Press My Button")
        my_layout.add_widget(self.my_first_button)
        my_layout.add_widget(self.my_first_label)
        return my_layout # return calls the build method which in turn builds the GUI.
TwoColumnApp().run() # Calls the TwoColumnApp object to run the app.

The Skinny On The GridLayout Code

The new code that adds the Label and builds the Grid Layout is as follows;

  • Line 3 of the code imports Kivy’s Label Screen Widget class for use in this app. This is done in the exact same manner as Kivy’s Button widget. (Line 4)
    • A label looks exactly like a button and its purpose is to display text only. The Label Widget has no “click” methods that you might expect when using a Button widget.
  • Line 10 of the code creates an instance of Kivy’s Label Widget and names the new label object “self.my_first_label”. Line 10 also assigns its text property  to “Please Press My Button”.This is done in the exact same manner as Kivy’s Button widget. (Line 9)
  • Line 2 of the code imports the GridLayout class for use in the app.
  • Line 7 of the code creates an instance of the GridLayout class and names the new GridLayout object my_layout.
    • From this point on any Screen Widgets added to the GUI will be added to the my_layout object and will be added to the GUI in a grid-like fashion as shown above.
  • Line 8 sets the column property of the my_layout to 2 columns
  • Line 11 adds the self.my_first_button widget to the my_layout object. Because my_layout is set to 2 columns and grid layouts populate from left to right, the button is placed on the left hand side of the screen.
  • Line 12 adds the self.my_first_label widget to the my_layout object. Because my_layout is set to 2 columns and grid layouts populate from left to right, the label is placed on the right hand side of the screen because the button occupies the first column.

Given the additional information on how the grid layout works, the final code for this post is as follows with each line commented to indicate what the code does;


from kivy.app import App # Imports the base App class required for Kivy Apps
from kivy.uix.gridlayout import GridLayout # imports the GridLayout class for use in the app.
from kivy.uix.label import Label # Imports the Label Screen Widget for use in the app.
from kivy.uix.button import Button # Imports the Button Screen Widget for use in the app.
class TwoColumnApp(App): # Creates the instance (copy) of the Kivy App class named TwoColumnApp.
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        my_layout = GridLayout() # Creates a GridLayout titled my_layout for use in the app.
        my_layout.cols = 2 # Sets my_layout column property to 2
        self.my_first_button = Button(text="I'm A Button. Press Me") # Creates a Button Widget instance and sets its text property to I'm A Button. Press Me.
        self.my_first_label = Label(text="Please Press My Button") # Creates a Label Widget instance and sets its text property to Please Press My Button.
        my_layout.add_widget(self.my_first_button) # Adds the button widget to my_layout
        my_layout.add_widget(self.my_first_label) # Adds the label widget to My_layout
        return my_layout # return calls the build method which in turn builds the GUI.
TwoColumnApp().run() # Calls the TwoColumnApp object to run the app.

Button vs. Label Widgets

Before concluding and moving on to the next blog post I just wanted to point out the difference the Button and Label widgets. If you mouse-click or touch the button you’ll notice that the button changes colour for an instant (shown below). If you do the same to the label, nothing happens. That is the fundamental difference between a label and a button. A buttons have methods that will eventually trigger an event. Labels are designed to display text only and as such have no direct interactivity.

gui

A Kivy Button Demonstrates Its Interactivity When Touched Or Mouse Clicked By Changing Its Colour For An Instant

What’s Next?

If you haven’t done so yet now would a good time to play around with Kivy’s GridLayout code by adding some widgets, increasing the columns and trying out the grid arrangement in rows instead of columns. In the next blog post you’ll learn how to code the button so, when touched or clicked, it will change the label text to Hello, world!

….brad….

Here is the link to the next post in this blog series: Kivy For The Non Computer Scientist – Part 5: Making A Kivy Button Do Something

Kivy For The Non Computer Scientist – Part 3: Kivy’s Hello, World! Examined

As mentioned in Part 1 of this blog series, kivy.org’s Hello, world! app is a good study as it’s written. It is a simple and complete piece of code that helps one build upon the principles found in Part 2 of this blog series. Kivy’s Hello World code is listed as follows;

29254863550_ce8cba560e_o

Its Python code is as follows;

from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
    def build(self):
        return Button(text='Hello World')

TestApp().run()

The Hello, world! app is written to reflect Kivy’s Object Oriented Programming (OOP) principles that are outlined in Part 2 of this blog series. Remember, if your new to it, objects are pieces of code that someone else has written for you. One interacts with objects by creating an instance of it (copying it) and then customizing its properties or calling its methods for use in your application.

Practically applied these OOP principles start with the first line of code in the app;

from kivy.app import App # Imports the base App class required for Kivy Apps
from kivy.uix.button import Button

class TestApp(App): # Creates the instance (copy) of the Kivy App class named TestApp
    def build(self):
        return Button(text='Hello World')

TestApp().run()

To create the “Hello World” text and button;

  • Line 2 of the code imports Kivy’s Button Widget for use in the app.
  • Line 6 of the code creates an instance of Kivy’s Button Widget with the buttons text property set to “Hello World”.
from kivy.app import App
from kivy.uix.button import Button # Imports the Button Widget for use in this app.

class TestApp(App):
    def build(self):
        return Button(text='Hello World') # Creates a Button Widget instance and sets it text property to "Hello World".

TestApp().run()

To place the “Hello World” button on the Kivy GUI;

  • Line 5 references the build method. build is a method of Kivy’s App class and was inherited by the TestApp object when it was created. build is an object that simply places screen widgets (in this case the button) on the GUI when called.
  • Line 6 starts with the command return. When the program is run, return calls the build method which in turn places the button with the “Hello World” text onto the GUI.
from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        return Button(text='Hello World') # return calls the build method which places button on GUI.

TestApp().run()

To start the Kivy GUI;

  • Line 8 calls the TestApp object to run.
  • It should be noted that when a Kivy app runs, it runs in a continuous loop until the the program is terminated.

Lessons Learned

To conclude one can see within the six lines of simple Python code that makes up Kivy’s “Hello World” application the magic of Object Oriented Programming (OOP). Within those six lines of code and as outlined in Part 2 of this blog series, one creates two instances of different Kivy classes and employs them as objects by either calling their methods or by customizing their properties. No where in the code did I –as the programmer– have to write the low level code that makes the basic Kivy GUI or the “Hello World” button operate. We’ll soon reach the point where we will want to make a button actually do something. But before we do that we’ll touch simply and quickly on Screen Layouts in the next blog post.

Below is the complete code for the Kivy “Hello World” app complete with comments on each line should you wish to play with the code and/or build upon it.

from kivy.app import App # Imports the base App class required for Kivy Apps
from kivy.uix.button import Button # Imports the Button Widget for use in this app.

class TestApp(App): # Creates the instance (copy) of the Kivy App class named TestApp
    def build(self): # build is a method of Kivy's App class used to place widgets onto the GUI.
        return Button(text='Hello World') # Creates a Button Widget instance and sets it text property to Hello World

TestApp().run() # Calls the TestApp object to run the app.

….brad….

Next blog post in this series: Kivy For The Non Computer Scientist – Part 4: A Little About Kivy’s Screen Layouts

Kivy For The Non Computer Scientist – Part 2: Concepts To Get A Handle On

My learning goal around Kivy was to produce a simple button, switch and checkbox interface. From my previous work with Tkinter I had a basic understanding of what screen widgets are. Screen Widgets are the pre-made buttons, labels and checkboxes etc. that make up a standard interface. For me my initial barriers in applying Kivy were in gaining a practical understanding of how the widgets Object Oriented Programming (OOP) worked and how Kivy’s screen layouts worked. Turned out the basic knowledge relating to working with screen layouts and widgets is OOP, so having a basic understanding of OOP is an essential component to work with Kivy.

Object Oriented Programming

In an interview for Rolling Stone magazine in 1994, Steve Jobs was asked about Object Oriented Programming. He replied as follows: ” Objects are like people. They’re living, breathing things that have knowledge inside them about how to do things and have memory inside them so they can remember things. And rather than interacting with them at a very low level, you interact with them at a very high level of abstraction.”

I find the best way to describe objects as code that somebody has already written for you. When you use an object you can alter it’s properties and employ its methods to make it useful for your particular application.

ben

 

Consider the image above. In programming nomenclature, the image shows a dog object. The object (or dog) is named Ben. Ben comes with several physical properties (height, weight, colour etc.) that as a programmer I can change and customize for my application. As well Ben comes with several methods such as sit and lay down. It’s pretty clear what these methods do and I can call these methods at any time in my code depending on what I want Ben to do.

The point of the Object is that I –as the programmer– didn’t have to write any of the low level code that ensures the height and weight work or any low level code to make Ben beg or sit. I as the programmer only have to customize the object via its properties and call its methods as needed. Hence the term Object Oriented Programming and the origin of Steve Jobs assertion that one interacts with an object at a much higher level.

If you’re a Python programmer you already understand that in order to get specialized objects (such as Kivy and its screen widgets) you first must add the library to your Python installation. This is usually done using PIP and the installation procedure is well documented on the kivy.org website.

instance

To both make and use an object one must first create an instance (ie. a copy) of it via ones computer code. One can then alter the properties of the object and call any methods as required. Note in its original form the object is referred to as a class. Only when an instance of it is made is it referred to as an object. One can use an object as many times as they wish by creating additional instances of it usually with a different name. When several instances of an object are created, each different object can be garnished with unique properties –such as colour and size in the above example– and methods will only occur when the specific objects method is called.

The Use Of Objects In Kivy

kivy-gpio-raspberry-pi-touch-thumb

Given the above explanation of OOP it’s not hard to understand that each of Kivy’s screen widgets are invoked as objects. If you watched Matt Richardson’s video in Part 1 of this Kivy training blog, you can plainly see buttons and the slider screen widgets he employed when developing his GUI. You would probably understand that the button widget and slider widget are different widgets and might have different properties and methods. As well his GUI implementation employs three different instances of the same button class used to control the different hardware elements installed on his breadboard.

Kivy’s Screen Layouts Are Also Objects And Nested

Currently Kivi has eight different screen layouts. If you’re new to Kivy I would avoid reading about them at this time as the documentation is detailed and once you learn how to invoke them you’ll require the detail. As mentioned above the screen layouts too are invoked as objects. Their purpose is to provide the base on which one places the appropriate GUI screen widgets. The reason that there are different screen layouts is because the properties differ from layout to layout on how widgets are positioned.

Here is the key thing to know about Kivy’s screen layouts. The reason it took so long for the “penny to drop” on how Kivy’s GUI’s are actually constructed for me was because a simple Kivy interface may actually contain several of these screen layouts. In other words its common practice that several different screen layouts may be nested in order to achieve the desired widget positioning.

Like the OOP concepts noted above, nested Kivy screen layouts are important concept to understand right from the start. It makes it a lot easier to understand the Python code when you read it. In my next blog post I’ll introduce some simple code that will help you grasp the concepts outlined in this post as quickly as possible.

….brad….

Next post in this blog series: Kivy For The Non Computer Scientist – Part 3: Kivy’s Hello, World! Examined

Kivy For The Non Computer Scientist – Part 1: Making It Simple

The Python Programming Language has taken me almost three years to learn. It was an undertaking I started when I retired from my job at Ryerson University. With little formal training in computer science and no continuing education classes that I could attend in Toronto, my only option has been to learn with a combination of online sources and with books. I can now look back and say my learning and development was hampered by the lack of simple, straightforward code examples from which I could learn from.

I was continuously amazed when searching the Internet for code examples only to come across thousands of complex answers to simple questions which (for me) was a real barrier to me learning to code. Not all of us learners on the Internet have advanced math skills, nor can we wrap our heads fully around all the elements associated with Object Oriented programming that accompany many API‘s. And until these concepts can be taught with simplicity, coding will –IMHO– be difficult to democratize.

After completing my first major open source project in Python (www.convergencejukebox.com) I realized how hard it had been to learn many of Pythons advanced concepts. While there are many basic introductions to Python on the Internet the simple ones always seemed to cover the same topics and it was rare to find anything that was intermediate that built one could build from simple code. These days I do seem to be able to put code together with confidence but when coding something new a lack of simple code examples out here in the cloud really slows me down as I learn it a new application.

In trying to improve upon what I learned over the past few years I decided it would be a good time to tackle a new GUI application for Python called Kivy (see above video on Kivy by Matt Richardson). My Jukebox project (also noted above) used Tkinter as it’s GUI. Tkinter is part of Pythons standard libraries and works fine as a GUI on Linux, Windows and Macintosh computers. I’d be lying if I said I had mastered Tkinter as I coded that project. After reading about Kivy’s features, coupled with my experience using Tkinter, Kivy’s concepts seem more logical to implement and some of its features are more modern in design.

Kivy has two concepts that I personally find hard to swallow:

  1. It’s object oriented (which in concept is great) but I’ve found its nomenclature difficult to understand. I don’t think I’m alone with my OOP struggles so simple code examples are a blessing to me when I actually find them.
  2. Kivy promotes using a separate file (.kv). It’s optional and its used to set properties of the various Kivy screen widgets. –The .kv file is something akin to CSS and HTML– Since I like all of my code in one file I opt not to use .kv file if I can avoid it. However much of the documentation to date employs using the separate .kv file and as such its hard for me find and synthesize relevant code examples.

But even with those drawbacks Kivy’s appeal to me is that the Python code written around it is portable to all platforms including IOS and Android. Kivy is fairly new with its first stable release in January of this year.

While the language appears to be well documented on its website, I find the example content created by the community to date lacking very simple examples. I’m facing the same struggle(s) I had learning Python. While I’m grateful people have taken the time to create example materials, too much of the content generated to date jumps almost immediately into Kivy’s cool features and –even worse– much of it seem to be the same material originating from the same source.

As well many of the initial adopters and testers of Kivy are seasoned computer professionals and the material produced is aimed at those with similar backgrounds. There is a lot of assumed knowledge in much of that material.

To my way of thinking training in Kivy (or any GUI) should start on building a simple button, switch and checkbox interface. For example today I wanted to find a simple basic program (in its entirety) that used a Kivy checkbox on its user interface… Think I could… Nope….

29254863550_ce8cba560e_o

Kivy’s Hello, world! application found at kivy.org.

from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
    def build(self):
        return Button(text='Hello World')

TestApp().run()

While I expected Kivy’s learning curve to be steep, it took me almost three weeks for the “penny to drop” on how to format a basic Kivy interface. The Kivy “Hello world,” example is easy (above) and it comes with complete simple code… (Thanks Kivy.org…) But after setting up the Kivy library on my PC, advancing skills in Kivy became a mind numbing adventure to find simple code that explained how to put a basic interface together. It then became another adventure to find out how to get a button to actually do something and today –for example– it took another morning of my life to understand how to get a checkbox to work. Kivy’s new, people are working hard to get the code to work, and –yes— I understand that it takes time to develop an understanding of something that is this new.

So what I thought I would do is use my blog to publish several short simple Kivy code snippets, outlining what I learned about applying Kivy from a non mathematician or computer scientist perspective.  They’ll appear as I learn the required concepts and I can simplify their explanation. Hope you find them useful.

Here is the link to the next post: Kivy For The Non Computer Scientist – Part 2: Concepts To Get A Handle On

….brad…