1

I have the following code:

class Channel(QObject):
    nameChanged = pyqtSignal()

    def __init__(self, props, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._name = props["name"]

    @pyqtProperty("QString", notify=nameChanged)
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name
        self.nameChanged.emit()

This works perfectly for my current (prototyping) needs. But let's say that props will have some more keys that I'm also interested in having as pyqtPrierty.

Is there a way I can generate the setter and the property methods for all the keys in props?

alexandernst
  • 14,352
  • 22
  • 97
  • 197
  • tryed with setattr - not works – eri Mar 25 '19 at 15:29
  • Possible duplicate of [Can anyone help condense this Python code?](https://stackoverflow.com/questions/11921320/can-anyone-help-condense-this-python-code) – eri Mar 25 '19 at 15:32

1 Answers1

1

Solution is generate new type dynamicly:

from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject

def getter(name):

    def wrapped(self):
        return self._proxy[name]
    return wrapped


def setter(name):
    def wrapped(self,v):
        self._proxy[name] = v
        getattr(self,'proxy_changed').emit()
    return wrapped


def dict2props(data):
    on_changed = pyqtSignal()
    r = {
        '_proxy': data,
        'proxy_changed': on_changed
        }

    for k in data:
        typ = type(data[k])
        setter.__name__ = "set_"+k
        getter.__name__ = "get_"+k
        r[k] = pyqtProperty(typ, fget=getter(k), fset=setter(k), notify=on_changed)
    return r



settings = {'as':12}
settingsproxy = type('Settings', (QObject,), dict2props(settings))()

Signal not tested (will edit answer then done). I used common Signal for all properties. But it can be generated too.

...

        def setter(self,v):
            self._proxy[k] = v
            getattr(self,k+'_changed').emit()

        r[k+'_changed'] = pyqtSignal()
        r[k] = pyqtProperty(typ,fget=lambda s: self._proxy[k], fset=setter, notify=r[k+'_changed'])
...
eri
  • 3,133
  • 1
  • 23
  • 35