Five Basic Exercises”- Royal Canadian Air Force 5BX Training Film (1959)

Advertisements

Kivy For The Non Computer Scientist – A Compendium Of Blog Posts To Date.

 

kivy

Earlier today I post my 18th blog post relating to what I have learned about Kivy. I thought it would be good at this time to provide a compendium of them in one place.

Here they are:

Part 1: Making It Simple

Part 2: Concepts To Get A Handle On

Part 3: Kivy’s Hello, World! Examined

Part 4: A Little About Kivy’s Screen Layouts

Part 5: Making A Kivy Button Do Something

Part 6: Code Cleanup And Kivy Convention

Part 7: Simple Checkbox Code

Part 8: Adding A Checkbox Label

Part 9: Dynamic Checkbox Labels

Part 10: KV Language

Part 11: Using KV Language To Set Widget Text Size, Text Position And Text And Button Colours

Part 12 – KV Language – Switching Between Kivy GUI Screens

Part 13: Creating More Complex Kivy GUI’s Using Nesting And KV Language

Part 14: Button Presses That Update Labels And Change Screens Using KV Language.

Part 15: Interacting With Python

Part 16: Reading Text From Kivy Buttons Created In KV Language For Use In Python Code.

Part 17: Making Natural Looking GUI’s Using Kivy’s Float Layout.

Part 18: How To Create Multi-screen Applications Using KV Language Then Update Individual Screens.

 

Kivy For The Non Computer Scientist – Part 18: How To Create Multi-screen Applications Using KV Language Then Update Individual Screens.

Long title! If you’ve been following the progress of my efforts to convert Convergence Jukebox to a Kivy based multi-screen application, I recently reached the point where I had completed the basic single screen version. It was now time to start on the multi-screen application. After my first attempt I ran into some major problems.

They were;

  1. Trying to build and code the screen management was clumsy using python. I realized it was time to “suck it up buttercup” and learn how to build the screen management in kv language.
  2. In trying to update the screen built in Part 17: Making Natural Looking GUI’s Using Kivy’s Float Layout of this series I could not figure out how to update the text on the various buttons and labels that was on the screen once it was placed in a multi-screen app. Because Kivy’s documentation is so scattered I went to StackOverflow.com and the discussions that formed this blog post can be found at;

In his post the kv language code will generate a four screen app, that will push through the four screens that have different text indicating their screen number. When completed the first screen will be re-pushed onto the screen with it’s text changed to indicate it’s screen five.

The app will look as follows as shown on this YouTube video;

The complete working code is as follows;

import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock # Imports Kivys clock object.
from kivy.uix.screenmanager import Screen

class FirstScreen(Screen): # Defines FirstScreen instance as a screen widget.
    pass

class SecondScreen(Screen): # Defines SecondScreen instance as a screen widget.
    pass

class ThirdScreen(Screen):# Defines ThirdScreen instance as a screen widget.
    pass

class FourthScreen(Screen):# Defines FourthScreen instance as a screen widget.
    pass

root_widget = Builder.load_string("""
ScreenManager:
    FirstScreen:
    SecondScreen:
    ThirdScreen:
    FourthScreen:
<FirstScreen>:
    _first_screen_text_: first_screen
    name: 'my_first_screen'
    Label:
        id: first_screen
        text: "Hi I'm The First Screen"
<SecondScreen>:
    _second_screen_text_: second_screen
    name: 'my_second_screen'
    Label:
        id: second_screen
        text: "Hi I'm The Second Screen"
<ThirdScreen>:
    _third_screen_text_: third_screen
    name: 'my_third_screen'
    Label:
        id: third_screen
        text: "Hi I'm The Third Screen"
<FourthScreen>:
    _fourth_screen_: fourth_screen
    name: 'my_fourth_screen'
    Label:
        id: fourth_screen
        text: "Hi I'm The Fourth Screen"
""")

class SwitchingScreenApp(App):
    def build(self):
        Clock.schedule_once(self.screen_switch_one, 2) # clock callback for the first screen
        Clock.schedule_once(self.screen_switch_two, 4) # clock callback for the second screen
        Clock.schedule_once(self.screen_switch_three, 6) # clock callback for the third screen
        Clock.schedule_once(self.screen_switch_four, 8) # clock callback for the fourth screen
        Clock.schedule_once(self.text_replace_screen_one, 9)# clock callback to change text the first screen
        Clock.schedule_once(self.screen_switch_one, 10) # clock callback for the first screen
        return root_widget

    def text_replace_screen_one(a,b):
        root_widget.get_screen('my_first_screen')._first_screen_text_.text = "Hi I'm The Fifth Screen" # code to change text on specific screen and widget.

    def screen_switch_one(a, b):
        root_widget.current = 'my_first_screen' # switches screen using Screen Managers current method and desired screens name.

    def screen_switch_two(a, b):
        root_widget.current = 'my_second_screen' # switches screen using Screen Managers current method and desired screens name.

    def screen_switch_three(a, b):
        root_widget.current = 'my_third_screen' # switches screen using Screen Managers current method and desired screens name.

    def screen_switch_four(a, b):
        root_widget.current = 'my_fourth_screen' # switches screen using Screen Managers current method and desired screens name.

if __name__ == '__main__':
    SwitchingScreenApp().run()

Setting Up The Multi-screen In KV Language

It’s lines 20 thru 47 in the code above that contains the kv language that builds our multi-screen base. Let’s go through the build line by line;

Line 21 – Invokes the Screen Manager. The screen manager is a widget dedicated to managing multiple screens for your application. Notice the format of the line of code… It’s not indented or enclosed in brackets. In kv language, which is a series of rules, this is how on declares the class of your root widget. In kv language you can only have one root rule (or widget). In this case we’ve called the ScreenManager class.

Lines 22 thru 25 – These lines both create and name the multiple screens that are found in this app. Notice the format of each line of code… This time they are indented. In kv language each indented line in this manner creates a child of the ScreenManager class. So in this case each line of code advises that a child (or an instance) will be created from this class and its name is provided.

Line 26 – Invokes the graphical instance of the first screen of our app. Note the format of this rule… The text is wrapped with brackets and followed with a colon. In kv language this is known as a class rule. Text in this format defines how instances of a class will be graphically represented.  In this case it’s the graphical representation of the apps first screen.

Line 27 – This is probably the most poorly documented rule in Kivy. This line provides access from outside the instance (or widget) to a screen property by Python. Without it one will never be able to access the screens properties from outside of Kivy.

To understand this better look at the relationship by observing Line 30. On this line the variable _first_screen_text_ is assigned the variable first_text. Now look at Line 30. Line 30 is the is the id of the screens Label widget. With this link in place one can now access the first screens label text in python via the _first_screen_text_ variable. You can look ahead and see how that variable is referenced and the text is changed on Line 63 of the code.

Also notice that I’ve added underscores to the beginning and end of the _first_screen_text_ variable’s name. This was done to remind me that this is my reference to the screens property from Python. This is not a hard and fast requirement, but as a program grows in complexity it’s useful to understand that this is the properties reference and exactly what property it is.

I’ve done my best to explain this rule. The documentation is found here. Hopefully you can make better sense of it than I can.

Line 28 – Sets the rule for the name of the screen that’s used by Kivys Screen Manager. The Name is used later in the code to select the screen to be displayed ( Lines 66, 69, 72, and 75) using its current property and the get a specific screen (Line 63) to change the first screens text. You’ll find the documentation for these methods in the Screen Managers api.

Line 29 – Declares that a label widget will be displayed on the screen.

Line 30 – This indented line provides the id for the label widget. It’s referenced in Line 27 as discussed above.

Line 31 – Is the text property of the label that will be displayed on the first screen.

Lines 32 thru 37 – Defines the kv language rules for the second screen.

Lines 38 thru 43 – Defines the kv language rules for the third screen.

Lines 44 thru 49 – Defines the kv language rules for the fourth screen.

Python Code

Line 8 – Defines that the FirstScreen instance created in kv language is a screen widget.

Line 11 – Defines that the SecondScreen instance created in kv language is a screen widget.

Line 14 – Defines that the ThirdScreen instance created in kv language is a screen widget.

Line 17 – Defines that the FourthScreen instance created in kv language is a screen widget.

Kivy’s Clock Object

In this application Kivy’s clock object is used to automatically switch between screens. The clock object allows one to schedule events at a specific time. The clock uses delta time as its time property. Delta time is the time between frames and is expressed in seconds. The clock calls functions (callbacks). Kivy’s clock does not execute individual lines of code directly but will execute an anonymous function or lambda.

In this application the clock object code is instantiated during the build process and each callback has it’s own line of code. So the clock object code is found as follows;

Line 5 – Imports Kivy’s clock object.

Line 54Kivy clock object code that calls for the first screen to be displayed after two seconds.

Line 55 – Kivy clock object code that calls for the second screen to be displayed at four seconds.

Line 56 – Kivy clock object code that calls for the third screen to be displayed at six seconds.

Line 57 – Kivy clock object code that calls for the fourth screen to be displayed at eight seconds.

Line 58 – Kivy clock object code that calls for the text on the first screen to be changed at nine seconds.

Line 59 – Kivy clock object code that calls for the first screen to be displayed (with the updated text) after ten seconds.

Lines 66, 69, 72, and 75 – Are the Kivy Clock callback(s) code that use Kivy’s Screen Manager’s current method to display the appropriate screen. Note the screens are identified by their name property.

Line 63 – Contains the code that changes the text on the first screen. This is done in one line of code by first calling the Screen Managers get_screen() function with the appropriate screen name (in this case my_first_screen), then identifying the specific widget (_first_screen_text_ as coded on Line 27) and then changing the labels text property with the appropriate code.

I hope this post helps you in your quest to learn Kivy….

….brad….

 

DjangoCon US 2017 – Understanding JavaScript Libraries via React.

How This Rusty Old Disk Inspired Television.

More Than Meets The Eye (1950 NBC promotional film)

EuroSciPy 2017: Working with Audio Data in Python