mirror of https://github.com/kivy/kivy.git
Made grammar and punctuation fixes.
This commit is contained in:
parent
daeb1885cc
commit
872bc4c80e
|
@ -12,12 +12,11 @@ The *Properties* classes are used when you create a
|
||||||
Kivy's property classes support:
|
Kivy's property classes support:
|
||||||
|
|
||||||
Value Checking / Validation
|
Value Checking / Validation
|
||||||
When you assign a new value to a property, the value is checked to pass
|
When you assign a new value to a property, the value is checked to
|
||||||
some constraints implemented in the class. I.e., validation is
|
pass constraints implemented in the class such as validation. For
|
||||||
performed. For example, an :class:`OptionProperty` will make sure that
|
example, validation for :class:`OptionProperty` will make sure that
|
||||||
the value is in a predefined list of possibilities.
|
the value is in a predefined list of possibilities. Validation for
|
||||||
A :class:`NumericProperty` will check that your value is a numeric type,
|
:class:`NumericProperty` will check that your value is a numeric type.
|
||||||
i.e. int, float, etc.
|
|
||||||
This prevents many errors early on.
|
This prevents many errors early on.
|
||||||
|
|
||||||
Observer Pattern
|
Observer Pattern
|
||||||
|
@ -32,30 +31,30 @@ Kivy's property classes support:
|
||||||
The same instance of a property is shared across multiple widget
|
The same instance of a property is shared across multiple widget
|
||||||
instances.
|
instances.
|
||||||
|
|
||||||
Comparaison Python / Kivy
|
Comparison Python / Kivy
|
||||||
-------------------------
|
------------------------
|
||||||
|
|
||||||
Basic example
|
Basic example
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
As an example, let's see some comparaison between Python and Kivy properties.
|
Let's compare Python and Kivy properties by creating a Python class with 'a'
|
||||||
Let's create a Python class with 'a' as a float::
|
as a float::
|
||||||
|
|
||||||
class MyClass(object):
|
class MyClass(object):
|
||||||
def __init__(self, a=1):
|
def __init__(self, a=1.0):
|
||||||
super(MyClass, self).__init__()
|
super(MyClass, self).__init__()
|
||||||
self.a = a
|
self.a = a
|
||||||
|
|
||||||
With Kivy, you can do::
|
With Kivy, you can do::
|
||||||
|
|
||||||
class MyClass(EventDispatcher):
|
class MyClass(EventDispatcher):
|
||||||
a = NumericProperty(1)
|
a = NumericProperty(1.0)
|
||||||
|
|
||||||
|
|
||||||
Value checking
|
Value checking
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you wanted to add some check like a minimum / maximum value allowed for a
|
If you wanted to add a check such a minimum / maximum value allowed for a
|
||||||
property, here is a possible implementation in Python::
|
property, here is a possible implementation in Python::
|
||||||
|
|
||||||
class MyClass(object):
|
class MyClass(object):
|
||||||
|
@ -74,8 +73,8 @@ property, here is a possible implementation in Python::
|
||||||
self._a = a
|
self._a = a
|
||||||
a = property(_get_a, _set_a)
|
a = property(_get_a, _set_a)
|
||||||
|
|
||||||
The disadvantage is you have to do that work yourself. And it start to be
|
The disadvantage is you have to do that work yourself. And it becomes
|
||||||
complex if you have lot of properties.
|
laborious and complex if you have many properties.
|
||||||
With Kivy, you can simplify like this::
|
With Kivy, you can simplify like this::
|
||||||
|
|
||||||
class MyClass(EventDispatcher):
|
class MyClass(EventDispatcher):
|
||||||
|
@ -87,18 +86,17 @@ That's all!
|
||||||
Conclusion
|
Conclusion
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
Even if we don't show a in-depth comparaison, you can understand how it's easier
|
Kivy properties are easier to use than the standard ones. See the next chapter
|
||||||
to create Kivy properties and use it than the standard one. See the next chapter
|
for examples of how to use them :)
|
||||||
to see how to use them :)
|
|
||||||
|
|
||||||
|
|
||||||
Observe Properties changes
|
Observe Properties changes
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
As we said in the beginning, Kivy's Properties implement the `Observer pattern
|
As we said in the beginning, Kivy's Properties implement the `Observer pattern
|
||||||
<http://en.wikipedia.org/wiki/Observer_pattern>`_. That's mean you can
|
<http://en.wikipedia.org/wiki/Observer_pattern>`_. That means you can
|
||||||
:meth:`~kivy.event.EventDispatcher.bind` to a property, and have your own
|
:meth:`~kivy.event.EventDispatcher.bind` to a property and have your own
|
||||||
callback called when the value change.
|
function called when the value changes.
|
||||||
|
|
||||||
Multiple ways are available to observe the changes.
|
Multiple ways are available to observe the changes.
|
||||||
|
|
||||||
|
@ -118,10 +116,10 @@ class::
|
||||||
ins = MyClass()
|
ins = MyClass()
|
||||||
ins.bind(a=callback)
|
ins.bind(a=callback)
|
||||||
|
|
||||||
# at this point, any change to the a property will call your callback
|
# At this point, any change to the a property will call your callback.
|
||||||
ins.a = 5 # callback called
|
ins.a = 5 # callback called
|
||||||
ins.a = 5 # callback not called, because the value didnt change
|
ins.a = 5 # callback not called, because the value didnt change
|
||||||
ins.a = -1 # callback called
|
ins.a = -1 # callback called
|
||||||
|
|
||||||
Observe using 'on_<propname>'
|
Observe using 'on_<propname>'
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -136,8 +134,8 @@ If you created the class yourself, you can use the 'on_<propname>' callback::
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
Be careful with 'on_<propname>'. If you are creating a such callback on a
|
Be careful with 'on_<propname>'. If you are creating such a callback on a
|
||||||
property you are inherit, you must not forget to call the possible subclass
|
property you are inherit, you must not forget to call the subclass
|
||||||
function too.
|
function too.
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,20 +160,19 @@ cdef class Property:
|
||||||
the observer list and storage initialisation. This class should not be
|
the observer list and storage initialisation. This class should not be
|
||||||
directly instantiated.
|
directly instantiated.
|
||||||
|
|
||||||
By default, a :class:`Property` always take a default value::
|
By default, a :class:`Property` always takes a default value::
|
||||||
|
|
||||||
class MyObject(Widget):
|
class MyObject(Widget):
|
||||||
|
|
||||||
hello = Property('Hello world')
|
hello = Property('Hello world')
|
||||||
|
|
||||||
The default value must be a value that agreed about the Property type. For
|
The default value must be a value that agrees with the Property type. For
|
||||||
example, you can't set a list to a :class:`StringProperty`, because the
|
example, you can't set a list to a :class:`StringProperty`, because the
|
||||||
StringProperty will check the default value.
|
StringProperty will check the default value.
|
||||||
|
|
||||||
None is a special case: you can set the default value of a Property to None,
|
None is a special case: you can set the default value of a Property to
|
||||||
but you can't set None to a property afterwise.
|
None, but you can't set None to a property afterward. If you really want
|
||||||
If you really want to do that, you must declare the Property with
|
to do that, you must declare the Property with `allownone=True`::
|
||||||
`allownone=True`::
|
|
||||||
|
|
||||||
class MyObject(Widget):
|
class MyObject(Widget):
|
||||||
|
|
||||||
|
@ -233,14 +230,14 @@ cdef class Property:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
cpdef bind(self, obj, observer):
|
cpdef bind(self, obj, observer):
|
||||||
'''Add a new observer to be called only when the value is changed
|
'''Add a new observer to be called only when the value is changed.
|
||||||
'''
|
'''
|
||||||
cdef list observers = obj.__storage[self._name]['observers']
|
cdef list observers = obj.__storage[self._name]['observers']
|
||||||
if not observer in observers:
|
if not observer in observers:
|
||||||
observers.append(observer)
|
observers.append(observer)
|
||||||
|
|
||||||
cpdef unbind(self, obj, observer):
|
cpdef unbind(self, obj, observer):
|
||||||
'''Remove the observer from our widget observer list
|
'''Remove the observer from our widget observer list.
|
||||||
'''
|
'''
|
||||||
cdef list observers = obj.__storage[self._name]['observers']
|
cdef list observers = obj.__storage[self._name]['observers']
|
||||||
for obj in observers[:]:
|
for obj in observers[:]:
|
||||||
|
@ -259,7 +256,7 @@ cdef class Property:
|
||||||
return a == b
|
return a == b
|
||||||
|
|
||||||
cpdef set(self, obj, value):
|
cpdef set(self, obj, value):
|
||||||
'''Set a new value for the property
|
'''Set a new value for the property.
|
||||||
'''
|
'''
|
||||||
value = self.convert(obj, value)
|
value = self.convert(obj, value)
|
||||||
d = obj.__storage[self._name]
|
d = obj.__storage[self._name]
|
||||||
|
@ -272,7 +269,7 @@ cdef class Property:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
cpdef get(self, obj):
|
cpdef get(self, obj):
|
||||||
'''Return the value of the property
|
'''Return the value of the property.
|
||||||
'''
|
'''
|
||||||
return obj.__storage[self._name]['value']
|
return obj.__storage[self._name]['value']
|
||||||
|
|
||||||
|
@ -297,18 +294,18 @@ cdef class Property:
|
||||||
|
|
||||||
cdef convert(self, obj, x):
|
cdef convert(self, obj, x):
|
||||||
'''Convert the initial value to a correctly validating value.
|
'''Convert the initial value to a correctly validating value.
|
||||||
Can be used for multiple types of argument, and simplify into only one.
|
Can be used for multiple types of arguments, simplifying to only one.
|
||||||
'''
|
'''
|
||||||
return x
|
return x
|
||||||
|
|
||||||
cpdef dispatch(self, obj):
|
cpdef dispatch(self, obj):
|
||||||
'''Dispatch the value change to all observers
|
'''Dispatch the value change to all observers.
|
||||||
|
|
||||||
.. versionchanged:: 1.1.0
|
.. versionchanged:: 1.1.0
|
||||||
The method is now accessible from Python.
|
The method is now accessible from Python.
|
||||||
|
|
||||||
This can be used to force the dispatch of the property, even if the
|
This can be used to force the dispatch of the property, even if the
|
||||||
value didn't changed::
|
value didn't change::
|
||||||
|
|
||||||
button = Button()
|
button = Button()
|
||||||
# get the Property class instance
|
# get the Property class instance
|
||||||
|
@ -326,9 +323,9 @@ cdef class Property:
|
||||||
|
|
||||||
|
|
||||||
cdef class NumericProperty(Property):
|
cdef class NumericProperty(Property):
|
||||||
'''Property that represents a numeric value
|
'''Property that represents a numeric value.
|
||||||
|
|
||||||
The NumericProperty accept only int or float.
|
The NumericProperty accepts only int or float.
|
||||||
|
|
||||||
>>> Widget.x = 42
|
>>> Widget.x = 42
|
||||||
>>> print Widget.x
|
>>> print Widget.x
|
||||||
|
@ -356,7 +353,7 @@ cdef class NumericProperty(Property):
|
||||||
cdef class StringProperty(Property):
|
cdef class StringProperty(Property):
|
||||||
'''Property that represents a string value.
|
'''Property that represents a string value.
|
||||||
|
|
||||||
Only string or unicode are accepted.
|
Only a string or unicode is accepted.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, defaultvalue='', **kw):
|
def __init__(self, defaultvalue='', **kw):
|
||||||
|
@ -440,7 +437,7 @@ class ObservableList(list):
|
||||||
cdef class ListProperty(Property):
|
cdef class ListProperty(Property):
|
||||||
'''Property that represents a list.
|
'''Property that represents a list.
|
||||||
|
|
||||||
Only lists are allowed, tuple or any other classes are forbidden.
|
Only lists are allowed. Tuple or any other classes are forbidden.
|
||||||
'''
|
'''
|
||||||
def __init__(self, defaultvalue=None, **kw):
|
def __init__(self, defaultvalue=None, **kw):
|
||||||
defaultvalue = defaultvalue or []
|
defaultvalue = defaultvalue or []
|
||||||
|
@ -514,7 +511,7 @@ class ObservableDict(dict):
|
||||||
cdef class DictProperty(Property):
|
cdef class DictProperty(Property):
|
||||||
'''Property that represents a dict.
|
'''Property that represents a dict.
|
||||||
|
|
||||||
Only dict are allowed, any other classes are forbidden.
|
Only dict are allowed. Any other classes are forbidden.
|
||||||
'''
|
'''
|
||||||
def __init__(self, defaultvalue=None, **kw):
|
def __init__(self, defaultvalue=None, **kw):
|
||||||
defaultvalue = defaultvalue or {}
|
defaultvalue = defaultvalue or {}
|
||||||
|
@ -558,7 +555,7 @@ cdef class ObjectProperty(Property):
|
||||||
self.name))
|
self.name))
|
||||||
|
|
||||||
cdef class BooleanProperty(Property):
|
cdef class BooleanProperty(Property):
|
||||||
'''Property that represents only boolean
|
'''Property that represents only a boolean value.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, defaultvalue=True, **kw):
|
def __init__(self, defaultvalue=True, **kw):
|
||||||
|
@ -574,7 +571,7 @@ cdef class BooleanProperty(Property):
|
||||||
|
|
||||||
cdef class BoundedNumericProperty(Property):
|
cdef class BoundedNumericProperty(Property):
|
||||||
'''Property that represents a numeric value within a minimum bound and/or
|
'''Property that represents a numeric value within a minimum bound and/or
|
||||||
maximum bound (i.e. a numeric range).
|
maximum bound -- within a numeric range.
|
||||||
|
|
||||||
:Parameters:
|
:Parameters:
|
||||||
`min`: numeric
|
`min`: numeric
|
||||||
|
@ -611,8 +608,8 @@ cdef class BoundedNumericProperty(Property):
|
||||||
storage['use_max'] = self.use_max
|
storage['use_max'] = self.use_max
|
||||||
|
|
||||||
def set_min(self, obj, value):
|
def set_min(self, obj, value):
|
||||||
'''Change the minimum value acceptable for the BoundedNumericProperty, only
|
'''Change the minimum value acceptable for the BoundedNumericProperty,
|
||||||
for the `obj` instance, None if you want to disable it::
|
only for the `obj` instance. Set to None if you want to disable it::
|
||||||
|
|
||||||
class MyWidget(Widget):
|
class MyWidget(Widget):
|
||||||
number = BoundedNumericProperty(0, min=-5, max=5)
|
number = BoundedNumericProperty(0, min=-5, max=5)
|
||||||
|
@ -637,8 +634,8 @@ cdef class BoundedNumericProperty(Property):
|
||||||
s['use_min'] = 1
|
s['use_min'] = 1
|
||||||
|
|
||||||
def get_min(self, obj):
|
def get_min(self, obj):
|
||||||
'''Return the minimum value acceptable for the BoundedNumericProperty in
|
'''Return the minimum value acceptable for the BoundedNumericProperty
|
||||||
`obj`, None if no minimum value are set::
|
in `obj`. Return None if no minimum value is set::
|
||||||
|
|
||||||
class MyWidget(Widget):
|
class MyWidget(Widget):
|
||||||
number = BoundedNumericProperty(0, min=-5, max=5)
|
number = BoundedNumericProperty(0, min=-5, max=5)
|
||||||
|
@ -654,9 +651,9 @@ cdef class BoundedNumericProperty(Property):
|
||||||
return s['min']
|
return s['min']
|
||||||
|
|
||||||
def set_max(self, obj, value):
|
def set_max(self, obj, value):
|
||||||
'''Change the maximum value acceptable for the BoundedNumericProperty, only
|
'''Change the maximum value acceptable for the BoundedNumericProperty,
|
||||||
for the `obj` instance, None if you want to disable it. Check
|
only for the `obj` instance. Set to None if you want to disable it.
|
||||||
:data:`set_min` for an usage example.
|
Check :data:`set_min` for a usage example.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
@ -672,9 +669,9 @@ cdef class BoundedNumericProperty(Property):
|
||||||
s['use_max'] = 1
|
s['use_max'] = 1
|
||||||
|
|
||||||
def get_max(self, obj):
|
def get_max(self, obj):
|
||||||
'''Return the maximum value acceptable for the BoundedNumericProperty in
|
'''Return the maximum value acceptable for the BoundedNumericProperty
|
||||||
`obj`, None if no maximum value are set. Check :data:`get_min` for an
|
in `obj`. Return None if no maximum value is set. Check
|
||||||
usage example.
|
:data:`get_min` for a usage example.
|
||||||
|
|
||||||
.. versionadded:: 1.1.0
|
.. versionadded:: 1.1.0
|
||||||
'''
|
'''
|
||||||
|
@ -701,7 +698,7 @@ cdef class BoundedNumericProperty(Property):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
property bounds:
|
property bounds:
|
||||||
'''Return min/max of the value
|
'''Return min/max of the value.
|
||||||
|
|
||||||
.. versionadded:: 1.0.9
|
.. versionadded:: 1.0.9
|
||||||
'''
|
'''
|
||||||
|
@ -755,7 +752,7 @@ cdef class OptionProperty(Property):
|
||||||
|
|
||||||
|
|
||||||
cdef class ReferenceListProperty(Property):
|
cdef class ReferenceListProperty(Property):
|
||||||
'''Property that allows to create a tuple of other properties.
|
'''Property that allows the creaton of a tuple of other properties.
|
||||||
|
|
||||||
For example, if `x` and `y` are :class:`NumericProperty`s, we can create a
|
For example, if `x` and `y` are :class:`NumericProperty`s, we can create a
|
||||||
:class:`ReferenceListProperty` for the `pos`. If you change the value of
|
:class:`ReferenceListProperty` for the `pos`. If you change the value of
|
||||||
|
@ -832,8 +829,8 @@ cdef class ReferenceListProperty(Property):
|
||||||
cdef class AliasProperty(Property):
|
cdef class AliasProperty(Property):
|
||||||
'''Create a property with a custom getter and setter.
|
'''Create a property with a custom getter and setter.
|
||||||
|
|
||||||
If you didn't find a Property class that fits to your needs, you can still
|
If you don't find a Property class that fits to your needs, you can make
|
||||||
create Python getters and setters and create a property with both of them.
|
your own by creating custom Python getter and setter methods.
|
||||||
|
|
||||||
Example from kivy/uix/widget.py::
|
Example from kivy/uix/widget.py::
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue