Kivy - Properties



A Property is a special class in Kivy that allows you to define and manage attributes of a widget or object. Property class is defined in the "kivy.properties" module. You can track changes to these attributes and they allow you to bind callback functions to be executed when the property changes.

Kivy's property classes support the following features −

Value Checking / Validation

Whenever a new value is assigned to a property, it is checked against validation constraints, in order to prevent errors. For example, validation for an OptionProperty will make sure that the value is in a predefined list of possibilities. Validation for a NumericProperty will check that your value is a numeric type.

Observer Pattern

You can specify what should happen when a property's value changes. You can bind your own function as a callback to changes of a Property. If, for example, you want a piece of code to be called when a widget's pos property changes, you can bind a function to it.

Better Memory Management

The same instance of a property is shared across multiple widget instances.

  • It may be noted that the Property objects are not the same as property() built-in function in Python.

  • A property object has to be declared at class level, not in any method of the class.

  • Each property by default provides an "on_<propertyname>" event that is called whenever the property's state/value changes.

Example

Let us study the behavior of Property in Kivy with the following example. The App class has a NumericProperty attribute. The NumericProperty object (value) is bound to on_value_change() method.

class NumPropApp(App):
   value = NumericProperty(0)

   def on_value_change(self, instance, value):
      print(f"Value changed: {value}")
      self.l1.text = str(value)

In the build() method, the app has a Label and a Button assembled in a vertical BoxLayout. The Button invokes onstart() method in response to on_press event and increments value with 1.

   def onstart(self, event):
      print ("started")
      self.value = self.value+1
   
   def build(self):
      lo = BoxLayout(orientation='vertical')
      self.l1 = Label(text=str(self.value), font_size = 50)
      self.b1 = Button(text = "start", font_size = 50)
      self.b1.bind(on_press=self.onstart)
      self.bind(value=self.on_value_change)
      lo.add_widget(self.l1)
      lo.add_widget(self.b1)
      return lo

Since the "on_value_change()" method is invoked on every change in value, the effect is that on every button press, the label caption shows increasing number from "0" onwards.

Here is the complete code of the example −

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.config import Config

# Configuration
Config.set('graphics', 'width', '720')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', '1')

class NumPropApp(App):
   value = NumericProperty(0)
   def on_value_change(self, instance, value):
      print(f"Value changed: {value}")
      self.l1.text = str(value)
   def onstart(self, event):
      print ("started")
      self.value = self.value+1
   def build(self):
      lo = BoxLayout(orientation='vertical')
      self.l1 = Label(text=str(self.value), font_size = 50)
      self.b1 = Button(text = "start", font_size = 50)
      self.b1.bind(on_press=self.onstart)
      self.bind(value=self.on_value_change)
      lo.add_widget(self.l1)
      lo.add_widget(self.b1)
      return lo

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

Output

Run the program from the command line. Press the button to see that every time the number displayed on the label increases.

Kivy Properties

Property Types

Kivy provides the following Property types −

NumericProperty − Handles numeric values such as integers and floats. It only accepts the int or float numeric data type or a string that can be converted to a number.

count = NumericProperty(0)

StringProperty − It is used to handle string values. You can initialize it with "defaultvalue" parameter.

text = StringProperty("start")

BoundedNumericProperty − This property is Similar to NumericProperty, but allows you to define minimum and maximum bounds for the value. It also supports get_min() and get_max() methods that return minimum and maximum acceptable values respectively.

a = BoundedNumericProperty(1, min=0, max=100)

BooleanProperty − Handles boolean values (True or False). The defaultvalue parameter can be set to True or False.

active = BooleanProperty(False)

ListProperty − The value of this property is a List object. When assigning a list to a ListProperty, the list stored in the property is a shallow copy of the list and not the original list.

colors = ListProperty([1, 0, 0, 1])

ObjectProperty − Handles a single object instance. If the rebind parameter is set to True, the associated kv rule will be re-evaluated and all the properties will be rebound when any intermediate property changes.

person = ObjectProperty(None)

OptionProperty − Specifies the default value of the property. It should be one from the list given in Options parameter. Example −

state = OptionProperty("None", options=["On", "Off", "None"])

ReferenceListProperty − This property is used to refer to one or more property objects of other types.

   x = NumericProperty(0)
   y = NumericProperty(0)
   z = ReferenceListProperty(x, y)

Changing the value of "z" will automatically change the values of "x" and "y" accordingly. If you read the value of "z", it will return a tuple with the values of "x" and "y".

AliasProperty − Provides an alias or alternative name for an existing property.

   def _get_width(self):
      return self.size
   def _set_width(self, value):
      self.size = value
   width = AliasProperty(_get_width, _set_width)

DictProperty − Used to define the initial value of an object with multiple parameters as the dictionary keys.

   params = DictProperty({
      'xlog': False,
      'xmin': 0,
      'xmax': 100,
      'ylog': False,
      'ymin': 0,
      'ymax': 100,
      'size': (0, 0, 0, 0)
   })

VariableListProperty − list items and to expand them to the desired list size.

obj = VariableListProperty(defaultvalue, length)

The defaultvalue parameter specifies the default values for the list. The length parameter is an int, either 2 or 4.

ConfigParserProperty − ConfigParserProperty lets you automatically listen to and change the values of specified keys based on other kivy properties.

ConfigParserProperty(defaultvalue, section, key, config)

A ConfigParser is composed of sections, where each section has a number of keys and values associated with these keys.

username = ConfigParserProperty('', 'info', 'name', None)

ColorProperty − Handles color values in various formats, such as RGB or hexadecimal. This property may be assigned any of the following values −

  • a collection of 3 or 4 float values between 0-1 (kivy default)

  • a string in the format #rrggbb or #rrggbbaa

  • a string representing color name (e.g., 'red', 'yellow', 'green')

Advertisements