Наследование нескольких свойств Kivy - PullRequest
1 голос
/ 13 июня 2019

Допустим, у меня есть 2 свойства kivy

  • первое свойство отвечает за то, чтобы значение находилось в определенном диапазоне (например, от 0 до 1) - для этого я использую BoundedNumericProperty
class MyBoundedProperty(BoundedNumericProperty):
    def __init__(self, *largs, **kw):
        self._my_min = kw.get('min', 0)  # 0 is default
        self._my_max = kw.get('max', 1.)  # 1 is default
        kw['min'] = self._my_min
        kw['max'] = self._my_max
        kw['errorhandler'] = self._my_errorhandler
        super().__init__(*largs, **kw)

    def _my_errorhandler(self, x):
        return min(max(x, self._my_min), self._my_max)
  • второе свойство отвечает за обеспечение того, чтобы значение всегда округлялось до пятого порядка (AliasProperty)
class MyAliasProperty(AliasProperty):
    _data = 0

    def __init__(self, **kwargs):
        kwargs['getter'] = self._getter
        kwargs['setter'] = self._setter
        super().__init__(**kwargs)

    def _getter(self, obj):
        return self._data

    def _setter(self, obj, value):
        if type(value) is int:
            value = float(value)
        if type(value) is float:
            self._data = round(value, 5)
        else:
            raise ValueError('{}.{} has an invalid format (got {!r})'.format(
                obj.__class__.__name__, self.name, value))
        return True  # Value changed, dispatch event

Я хотел быбыть в состоянии повторно использовать эти свойства при создании новых свойств, так как я делаю это с поведением виджета.Например: x = MyProperty (MyBoundedProperty, MyAliasProperty)

Это будет означать, что значение x должно быть 1) в указанных пределах (min и max) и 2) одновременно округляться до 5-го порядка.

Хочу уточнить - моя задача не использовать разные свойства (например, это может быть несколько свойств Alias).Моя задача - иметь возможность повторно использовать свойства, созданные ранее для создания составных свойств.

Есть ли способ сделать это?

PS позвольте мне немного прояснить это.Например:

class MyRoundProperty(AliasProperty):
    _data = 0.

    def __init__(self, **kwargs):
        kwargs['getter'] = self._getter
        kwargs['setter'] = self._setter
        super().__init__(**kwargs)

    def _getter(self, obj):
        return self._data

    def _setter(self, obj, value):
        if type(value) is int:
            value = float(value)
        if type(value) is float:
            pass
            self._data = round(value, 5)
        else:
            raise ValueError('{}.{} has an invalid format (got {!r})'.format(
                obj.__class__.__name__, self.name, value))
        return True  # Value changed, dispatch event
class MyBoundProperty(AliasProperty):
    _data = 0.
    _min = 0.
    _max = 1.

    def __init__(self, **kwargs):
        self._min = kwargs.pop('min', 0.)  # 0 is default
        self._max = kwargs.pop('max', 1.)  # 1 is default
        kwargs['getter'] = self._getter
        kwargs['setter'] = self._setter
        super().__init__(**kwargs)

    def _getter(self, obj):
        return self._data

    def _setter(self, obj, value):
        if type(value) is int or float:
            value = min(max(value, self._min), self._max)
            self._data = value
        else:
            raise ValueError('{}.{} has an invalid format (got {!r})'.format(
                obj.__class__.__name__, self.name, value))
        return True  # Value changed, dispatch event

Это работает:

class MyProperty(MyRoundProperty):
    pass

И это работает:

class MyProperty(MyBoundProperty):
    pass

Но это

class MyProperty(MyRoundProperty, MyBoundProperty):
    pass

ведет себя только как MyRoundProperty, и я хочу, чтобы MyProperty имел поведение обоих классов

1 Ответ

0 голосов
/ 13 июня 2019

Это похоже на ситуацию "нет, но да". Нет, вы, вероятно, не можете наследовать от нескольких свойств без проблем, они будут конфликтовать в управлении своим внутренним состоянием. Но да, вы, вероятно, можете достичь того, чего действительно хотите, разумным способом.

Вы можете сделать это несколькими способами, я не совсем понимаю, что вы делаете, и что, следовательно, будет лучшим вариантом. В простейшем случае вы могли бы просто добавить функцию округления к вашему MyBoundedNumericProperty, для меня неясно, действительно ли вы хотите использовать функцию в отдельном свойстве. Более гибкий вариант - сделать миксин похожим на поведение виджета, возможно, переопределяя метод свойства __set__.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...