【问题标题】:python ipyvuetify how to combine multiple widgets into a classpython ipyvuetify如何将多个小部件组合成一个类
【发布时间】:2021-03-14 20:49:13
【问题描述】:

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

是否可以创建一个自定义小部件,它包含不同的嵌套 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])

【问题讨论】:

    标签: python widget ipywidgets ipyvuetify


    【解决方案1】:

    到目前为止,我发现的最简单的解决方案是让 customWidget 类从我要显示的 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)
    
            
    

    【讨论】:

    • __init__函数的最后,可以直接在super().__init__调用中传递参数:super().__init__(v_model = [0], children = [panel], multiple = True, focusable = False, **kwargs)
    【解决方案2】:

    您不想包括以下内容:

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

    那你就可以走了:

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

    【讨论】:

    • 不,那样的话我也可以直接拨打c1.expansionPanel。我想要实现的是通过调用c1 来显示整个内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    相关资源
    最近更新 更多