python ipyvuetify如何将多个widget组合成一个class

python ipyvuetify how to combine multiple widgets into a class

使用 ipyvuetify,我必须在 ExpansionPanel 中重复使用一对 TextfieldTextarea。 它们的交互是相关联的,因为它们代表数据库行中的两个字段。

是否可以创建自定义小部件,它包含不同的嵌套 ipyvuetify 小部件,并允许作为单个对象与整个组进行交互,并且在调用时也像小部件一样呈现?

像这样:

import ipyvuetify as vue

Class customWidget():
    def __init__(self, titleText, bodyText):

        title = vue.TextField(class_='mb-n2', label='Label')
        title.value = titleText
        title.on_event('click.stop', None)
        openIn= vue.Btn(text=True, max_width='10px', children=[vue.Icon(children=['open_in_new'])])
        openIn.on_event('click.stop', None)


        note = vue.Textarea(class_='ma-0 pa-0 text-xs-caption', name='markerA', solo=True, elevation=0, outlined=True)
        note.value = bodyText

        panel = vue.ExpansionPanel(class_='ma-0 pa-0 text-xs-caption', children=[
            vue.ExpansionPanelHeader(class_='ma-0 pa-0 pl-5 pr-5', children=[title, openIn]),
            vue.ExpansionPanelContent(class_='ma-0 pa-0 text-xs-caption', children=[note]),
        ])

        self.expansionPanel = vue.ExpansionPanels(v_model=[0], multiple=True, focusable=False, children=[panel])

你不想加入类似这样的内容吗:

def display(self):
     display(self.expansionPanel)

那你可以去:

c1=customWidget('whatever tieltle','whatever bodytext')

c1.display()

到目前为止我找到的最简单的解决方案是使 customWidget class 继承自我想要显示的 ipyvuetify 小部件,并在构造函数中使用嵌套的其他小部件预填充它。

这非常有效,即使在深层嵌套结构中也可以设置为仍然可以访问每个元素。

注意不要覆盖 ipyvuetify 已经使用的属性名称。

在上述情况下,我的解决方案如下所示:


import ipyvuetify as vue

class customWidget(vue.ExpansionPanels):

    def __init__(self, titleText, bodyText, **kwargs):

        children = []

        title = vue.TextField(
            class_ = 'mb-n2',
            label = 'Label'
        )
        title.value = titleText
        title.on_event('click.stop', None)


        openIn = vue.Btn(
            text = True,
            max_width = '10px',
            children = [
                vue.Icon(
                    children = ['open_in_new']
                )
            ]
        )
        openIn.on_event('click.stop', None)


        note = vue.Textarea(
            class_ = 'ma-0 pa-0 text-xs-caption',
            name = 'markerA',
            solo = True,
            elevation = 0,
            outlined = True
        )
        note.value = bodyText

        panel = vue.ExpansionPanel(
            class_ = 'ma-0 pa-0 text-xs-caption',
            children = [
                vue.ExpansionPanelHeader(
                    class_ = 'ma-0 pa-0 pl-5 pr-5',
                    children = [
                        title,
                        openIn
                    ]
                ),
                vue.ExpansionPanelContent(
                    class_ = 'ma-0 pa-0 text-xs-caption',
                    children = [
                        note
                    ]
                ),
            ]
        )

        # add elements to kwargs, this allows to still pass others via the instance call
        kwargs['v_model'] = [0]
        kwargs['children'] = [panel]
        kwargs['multiple'] = True
        kwargs['focusable'] = False
        
        super().__init__(**kwargs)