There are number of ways to do it: class decorator, metaclass, Mixin.
Common helper function:
def set_pyqtproperties(klass, properties, proxy='user'):
def make_prop(prop):
def property_(self):
return getattr(getattr(self, proxy), 'get_' + prop)
property_.__name__ = prop
return property_
if isinstance(properties, basestring):
properties = properties.split()
for prop in properties:
setattr(klass, prop, pyqtProperty(QVariant, make_prop(prop)))
Class decorator
def set_properties(properties):
def decorator(klass):
set_pyqtproperties(klass, properties)
return klass
return decorator
Usage
@set_properties("display background")
class LightDMUser(QObject): pass
if there is no support for class decorators then you could try:
class LightDMUser(QObject):
pass
LightDMUser = set_properties("display background")(LightDMUser)
Metaclass
def set_properties_meta(properties):
def meta(name, bases, attrs):
cls = type(name, bases, attrs)
set_pyqtproperties(cls, properties)
return cls
return meta
Usage
class LightDMUser(QObject):
__metaclass__ = set_properties_meta("display background")
Note: you could reuse the same metaclass if you set the list of properties as a class attribute:
def MetaClass(name, bases, attrs):
cls = type(name, bases, attrs)
set_pyqtproperties(cls, attrs.get('properties', ''))
return cls
class LightDMUser(QObject):
properties = "display background"
__metaclass__ = MetaClass
Also you could manipulate attrs
directly: attrs[name] = value
before calling type()
instead of setattr(cls, name, value)
.
The above assumes that QObject.__class__ is type
.
Mixin
def properties_mixin(classname, properties):
#note: create a new class by whatever means necessary
# e.g., even using exec() as namedtuple does
# http://hg.python.org/cpython/file/3.2/Lib/collections.py#l235
# reuse class decorator here
return set_properties(properties)(type(classname, (), {}))
Usage
PropertiesMixin = properties_mixin('PropertiesMixin', 'display background')
class LightDMUser(PropertiesMixin, QObject): pass
I haven't tried any of it. The code is here to show the amount and the kind of code it might require to implement the feature.