condense pyqtproperties
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.
You could attach these methods from еру outside of the class definition:
class LightDMUser(QObject):
def __init__(self, user):
super(LightDMUser, self).__init__()
self.user = user
The simplest way is to create a closure for each property, override its __name__
(just for case if @pyqtProperty
needs it) and to bind it to the class:
for attribute in [
'background',
'display_name',
'has_messages',
'home_directory',
'image',
'language',
'layout',
'layouts',
'logged_in',
'name',
'real_name',
'session'
]:
def delegating(self):
return getattr(self.user, 'get_' + attribute)()
delegating.__name__ = attribute
delegating = pyqtProperty(QVariant)(delegating)
setattr(LightDMUser, attribute, delegating)