动态扩展小部件库

时间:2019-10-23 01:54:55

标签: python python-3.x kivy

我需要根据传递的参数来更改某些小部件类的基数。

最简单的示例是:

class A:
    def a(self):
        print (1)

class B:
    def __init__(self):
        self.extend_instance(A)
        self.a()

    def extend_instance(obj, cls):
        base_cls = obj.__class__
        base_cls_name = obj.__class__.__name__
        obj.__class__ = type(base_cls_name, (base_cls, cls),{})

B()

这可能不是最佳方法,因为每次创建新的B实例时,它都会改变基数(如果我不理解的话)。但这似乎可行。

这是一个非常简化的示例(不带参数,取决于应创建具有不同基础的B类实例)。

现在我正在尝试使用kivy小部件实现此

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label


class CoolLabel(Label):
    def a(self):
        print (1)


class MyLabel:
    def __init__(self, **kwargs):

        #self.__basses__ = CoolLabel

        self.extend_instance(CoolLabel)

        self.a()


    def extend_instance(obj, cls):
        base_cls = obj.__class__
        base_cls_name = obj.__class__.__name__
        obj.__class__ = type(base_cls_name, (base_cls, cls),{})


class MyApp(App):
    def build(self):
        self.root = MyLabel(text= '123456')


MyApp().run()

我收到此错误:

   File "main.py", line 24, in extend_instance
     obj.__class__ = type(base_cls_name, (base_cls, cls),{})
 TypeError: __class__ assignment: 'MyLabel' object layout differs from 'MyLabel'

是什么原因?这可以与kivy Widget元类相关吗? 并有任何解决方法吗?

更新:

让我简化我的问题。 主要问题是-为什么这行不通?

from kivy.uix.widget import Widget

class MyWidget:
    def __init__(self, **kwargs):
        self.__class__ = type('MyWidget', (Widget,),{})

MyWidget()

这是我的错误:

   File "main.py", line 7, in <module>
     MyWidget()
   File "main.py", line 5, in __init__
     self.__class__ = type('MyWidget', (Widget,),{})
 TypeError: __class__ assignment: 'MyWidget' object layout differs from 'MyWidget'

1 个答案:

答案 0 :(得分:0)

看起来像这样:

from kivy.event import EventDispatcher

class SomeWidget(EventDispatcher):
    def a(self):
        print ('hi')

class MyWidget(EventDispatcher):
    def __init__(self, **kwargs):
        self.__class__ = type('MyWidget', (SomeWidget,),{})
        self.a()

MyWidget()

尽管我仍然不明白这与什么有关。 我刚刚假设(由于@eyllanesc评论)该错误是由于碱基不兼容引起的,某种程度上与用cython编写的kivy EventDispatcher有关。