简体   繁体   English

如何创建多个ipywidget?

[英]How to create a ipywidgets from multiple ones?

Let's say I want a widget composed of an IntText widget and a DropDown widget which value is a concatened string of those widgets values. 假设我想要一个由IntText小部件和DropDown小部件组成的小部件,该值是这些小部件值的串联字符串。 How can I do? 我能怎么做?

Here is an attempt: 这是一个尝试:

import re
import ipywidgets as ipw

from IPython.display import display


class IntMultipliedDropdown:
    _VALUE_PATTERN = re.compile('(?P<num>\d+) (?P<option>\w+-?\w*)')

    def __init__(self, options, option_value, int_value=1):
        self.number = ipw.IntText(int_value)
        self.options = ipw.Dropdown(options=options, value=option_value)
        self.box = ipw.HBox([self.number, self.options])

        self.number.observe(self._on_changes, names='value')
        self.options.observe(self._on_changes, names='value')

        self._handelers = []

    def _on_changes(self, change):
        for handeler in self._handelers:
            handeler(self.value)

    @property
    def value(self):
        return "{} {}".format(self.number.value, self.options.value)

    @value.setter
    def value(self, value):
        match = re.search(self._VALUE_PATTERN, value)
        groupdict = match.groupdict()
        self.number.value = groupdict['num']
        self.options.value = groupdict['option']

    def _ipython_display_(self, **kwargs):
        return self.box._ipython_display_(**kwargs)

    def observe(self, handler):
        if handler not in self._handelers:
            self._handelers.append(handler)


mywidget = IntMultipliedDropdown(['apple', 'bed', 'cell'], 'cell')
mywidget.observe(print)

display(mywidget)
print('default value:', mywidget.value)

mywidget.value = '2 bed'

It works but has drawbacks. 它有效,但有缺点。 First, when I set mywidget.value the observed function is called two times: on number value change and on option value change. 首先,当我设置mywidget.value ,观察到的函数被调用了两次:数字值更改和选项值更改。

Second and worst is that I cannot use this widget in a Box widget like: 其次,最糟糕的是,我无法在Box小部件中使用此小部件,例如:

ipw.HBox([ipw.Label('Mylabel'), mywidget])

Which raises: 引起了:

ValueError: Can't clean for JSON: <__main__.IntMultipliedDropdown object at 0x7f7d604fff28>

Is there a better solution? 有更好的解决方案吗?

  1. The class you created is not a widget, although you did mimick some of the behaviors ( observe , display ). 您所创建的类不是一个小部件,你虽然模拟天生的一些行为(的observedisplay )。 This is probably why you couldn't get it to display in an HBox . 这可能就是为什么您无法将其显示在HBox If you want to create a new widget, inherit from ipyw.Widget or any other widget. 如果要创建新的小部件,请从ipyw.Widget或任何其他小部件继承。
  2. You have two underlying widgets that are being listened to, so it is normal that two functions get called when you change their values. 您有两个正在监听的底层小部件,因此在更改它们的值时通常会调用两个函数。 If you want only one function to be called, listen directly to the value of your new widget. 如果只希望调用一个函数,请直接侦听新窗口小部件的value

This is how you could do it, by inheriting from HBox : 通过从HBox继承,可以做到这一点:

import re
import ipywidgets as ipw
from traitlets import Unicode
from IPython.display import display


class IntMultipliedDropdown(ipw.HBox):
    _VALUE_PATTERN = re.compile('(?P<num>\d+) (?P<option>\w+-?\w*)')
    value = Unicode()

    def __init__(self, options, option_value, int_value=1, **kwargs):
        self.number = ipw.IntText(int_value)
        self.options = ipw.Dropdown(options=options, value=option_value)

        self._update_value()

        self.number.observe(self._update_value, names='value')
        self.options.observe(self._update_value, names='value')
        self.observe(self._update_children, names='value')

        super().__init__(children=[self.number, self.options], **kwargs)


    def _update_children(self, *args):
        match = re.search(self._VALUE_PATTERN, self.value)
        groupdict = match.groupdict()
        self.number.value = groupdict['num']
        self.options.value = groupdict['option']

    def _update_value(self, *args):
        self.value = "{} {}".format(self.number.value, self.options.value)

mywidget = IntMultipliedDropdown(['apple', 'bed', 'cell'], 'cell')
display(mywidget)

There likely is a reason why you went to all the trouble of creating a new widget, but why not use the interactive function ? 您可能会费尽心思来创建新的小部件,但是为什么不使用interactive功能呢?

Something like: 就像是:

import ipywidgets as ipw
from ipywidgets import *

w_number = ipw.IntText(value = 1)
w_options = ipw.Dropdown(options = ['apple', 'bed', 'cell'], value ='cell')

mywidget_value = ''

def display_value(number, options):
    mywidget_value = str(number)+' '+options
    #print(mywidget_value)
    return mywidget_value

w_box = interactive(display_value, number=w_number, options=w_options)

display(w_box)

Then you have a Box , and you can adapt its layout. 然后,您将获得一个Box ,并且可以调整其布局。 You can also access the keyword arguments with w_box.kwargs or the return value of the function with w_box.result , which is the concatenated string of the 2 widgets that you were looking for... 您还可以使用w_box.kwargs访问关键字参数,或使用w_box.kwargs访问该函数的返回值, w_box.result是您要查找的2 w_box.result部件的串联字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从容器中的多个 ipywidget 中卸载值 - Unloading values from multiple ipywidgets in a container 如何离线安装ipywidgets(从文件) - How to install ipywidgets offline (from file) 从 ipywidgets FileUpload 访问来自多个上传文件的内容 - Access the content from multiple uploaded files from ipywidgets FileUpload 如何使用 ipywidgets 创建一个工具按钮来显示和清除输出? - How to create a toogle button to show and clear output using ipywidgets? 如何使用 ipywidgets 创建动态依赖下拉菜单? - How to create a dynamic dependent dropdown menu using ipywidgets? 如何使用 Jyupyter 笔记本使用 ipywidgets 在循环中创建图形选项卡? - How to create figure tabs in a loop using ipywidgets using Jyupyter notebook? 如何使用相同的 label 使具有多个按钮的 ipywidgets.ToggleButtons - How to have an ipywidgets.ToggleButtons with multiple buttons using the same label 如何从指定长度的张量创建一为零的张量 - How to create a Tensor of ones and zeros from a tensor specifying lengths ipywidgets:如何根据复选框选择更新多个系列的绘图 - ipywidgets: how to update plot with multiple series based on checkbox selection 为什么 html 文件中没有定义来自 ipywidgets 的小部件? - How come widgets from ipywidgets is not defined in an html file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM