Google Analytics

Saturday, April 5, 2014

Kivy - Using ObjectProperty

I'm learning Kivy to use as the GUI interface to my Home Secutiry/Automation system.

This is a fairly new language, but looks to me like its going to be a good fit for my project, as well as growing in popularity.

Because it's new, there's not a lot of examples that I've been able to find, and the two books I've looked at jump a little too fast for me.

I solve this by writing a lot of small example programs to teach myself the underlying structure - this post is one of those examples.

In a MVC (Model, View, Controller), Python is performing the Control function, and Kivy is performing the View function (presentation); I don't really have a Model function in this example.

I've been having a lot of difficulty understanding the usage Kivy's ObjectProperty() call in Python.

Here's what I understand, and the examples (Python code and Kivy code) follow.

--UPDATE 4/5/14: I think it would be easier to use dynamic classes in .kv instead of the empty Python classes with 'pass'.  For example, below for Python, remove 'class Zone1' and in .kv change : to I haven't changed the code below to reflect this.
--

In Python, the following entries are made in a class:

class Zones(BoxLayout):
    labelText = ObjectProperty(None)
    basement   = ObjectProperty(None)

The two objects ('thispage' and 'basement') are references to the classes defined in the associated .ky file.

Here's the .ky file entry for those two class definitions:

:
    some_text: "This is Label text"

:
    zoneName: "Basement - Door and Windows"

Those two class definitions in the .ky file, must also have an entry in the in the .py file.  So back to the .py file to add these two classes (they aren't going to perform any logic, so I'm just setting their work to be performed to 'pass'):

class LabelText(Widget):
    pass

class Zone1(Widget):
    pass

Now back to the .ky file.  Within this file, so far, are the class definitions for Kivy - the LabelText class and the Zone1 class.  This represents the layout work that's going to be done by Kivy - the presentation.

Next I'm going to associate the Python objects 'labelText' and 'basement' with the two Python/Kivy classes 'LabelText' and 'Zone1'.

Adding a new class : to the Kivy .kv file, will give part of the association to the labelText and basement references, but it's not the final reference; there will be two more yet, where the Zone class is using the two widgets (classes) LabelText and Zone1.  

:
    labelText:   label_text
    basement:   zone1

    LabelText:
        id: label_text
    Zone1:
        id: zone1


So following Python code 'basement' entry:

    basement   = ObjectProperty(None)

Refers to the reference name assigned in Kivy .ky file to the widget id (where 'basement' is the tie to Python, and 'zone1' is the widget's ID in .ky):

    basement:   zone1

Then within Kivy, the zone1 is finally defined as the widget ID for the class instance :

    Zone1:
        id: zone1

So, bare bones, for basement/Zone1 we've got:

==== Python .py file ====

class Zone1(Widget):
    pass

class Zones(BoxLayout):
    labelText = ObjectProperty(None)
    basement   = ObjectProperty(None)


==== Kivy .ky file ====

:
    zoneName: "Basement - Door and Windows"

:
    basement:   zone1

    Zone1:
        id: zone1


Here's a PNG of the output, followed by the Python and Kivy code, with some additional features added (couple of more buttons), and a print utility (to your terminal window):



==== Python Code ====
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  TestProperties1.py
#  
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout


class LabelText(Widget):
    pass

class Zone1(Widget):
    pass

class Zone2(Widget):
    pass

class Zone3(Widget):
    pass
    
class Zones(BoxLayout):
    labelText = ObjectProperty(None)
    basement   = ObjectProperty(None)
    sunroom    = ObjectProperty(None)
    livingroom = ObjectProperty(None)
    
    def printzonenames(self):
        print("labelText: ", self.labelText.some_text)
        print("basement: ", self.basement.zoneName)
        print("sunroom: ", self.sunroom.zoneName)
        print("livingroom: ", self.livingroom.zoneName)

class TestProperties1(App):
    def build(self):
        theZones = Zones()
        theZones.printzonenames()
    


def main():
    TestProperties1().run()
    
    return 0

if __name__ == '__main__':
    main()

=======Python Code End=========

=======Kivy Code ============

#testproperties1.kv

Zones:

:
    some_text: "This is Label text"

:
    zoneName: "Basement - Door and Windows"

:
    zoneName: "Sunroom - Door and Windows"
    
:
    zoneName: "Living Room - Area"

:
    orientation: 'vertical'
    
    labelText:   label_text
    basement:   zone1
    sunroom:    zone2
    livingroom: zone3

    
    LabelText:
        id: label_text
    Zone1:
        id: zone1
    Zone2:
        id: zone2
    Zone3:
        id: zone3



    Label:
        text: label_text.some_text
    Button:
        text: zone1.zoneName
    Button:
        text: zone2.zoneName
    Button:
        text: zone3.zoneName

    
=======Kivy Code End =====    




No comments:

Post a Comment