[英]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? 有更好的解决方案吗?
observe
, display
). observe
, display
)。 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
或任何其他小部件继承。 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.