Before you start publishing controls, please thoroughly read these rules. They make both your and the users' lives easier.
Controls are Python classes derived from the Control base class and from the interfaces which they implement. The base class can be loaded from libdesklets.controls:
from libdesklets.controls import Control
Each control has its own directory, which at least consists of the __init__.py file. That file initializes the control and provides a function get_class() returning the main class (not an instance of the class) of the control.
The typical directory structure of a control looks like:
MyControl/ IMyInterface.py __init__.py
The control directory has to include all interface files from which the control inherits. By convention, the filenames of interface files start with an "I" to distinguish them from regular files. The file __init__.py is also mandatory. If neccessary, a control can also include other files as well, which are loaded by the initialization file. You should, however, keep in mind to design controls as generic as possible.
Every control implements one or more interfaces. Since an interface is a simple Python class, you just have to derive your control from the interface classes:
from libdesklets.controls import Control
from IMyInterface import IMyInterface
class MyControl(Control, IMyInterface):
def __init__(self):
Control.__init__(self)
...
...
def get_class(): return MyControl
Because interfaces are implementation-less, there is no super-constructor to invoke for them.
Always remember to derive from the Control class and to invoke its constructor to get a valid control class.
Every property in the interfaces must be implemented by creating appropriate property objects.
Python's property constructor takes four arguments, of which are all optional. From the Python inline help:
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
# fget is a function to be used for getting an attribute value. Likewise,
# fset is a function for setting an attribute and fdel is a function for
# deleting an attribute. Typical use is to define a managed attribute x:
class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")
The fdel argument is not needed for controls. If a property is not readable, you also omit the fget argument or set it to None. Likewise, for non-writable properties, omit the fset argument. The read-write permissions must match those declared by the interfaces.
The doc argument can be used for describing the property in human-readable form. It is highly recommended to give a useful description for every property. Doing so makes it easier for others to use your control.
The Control class provides you with all you need for writing compliant controls. The following methods can be used inside controls:
| Method Name | Arguments | Description |
|---|---|---|
| __init__ | The constructor of the Control. This always has to be called as the super-constructor within the constructor. | |
| _add_timer |
interval: integer callback: function *args |
This is a convenience function for adding a timeout handler which gets called after interval milliseconds. If the callback function returns True, the callback will be called again after the next timeout. This method returns an ID which can be used with _remove_timer() to remove the timer again. |
| _remove_timer |
ident: integer |
Removes the timer with the given ID ident. |
| _shutdown | This is a hook method which can be overridden in order to perform cleanup operations before the control is being closed. | |
| _update |
prop: string |
Notifies observers of property prop that the value has changed. You have to call this method whenever a property which is watchable using bind() changes its value. Of course it does not make sense for all properties to be watchable. Always call this method after the change has actually taken place. |