Jupyter:如何更改 SelectMultiple() 等小部件的颜色?
问题描述
挑战:
如何更改
我的尝试:
我以为我在使用
但令我非常失望的是,您似乎无法以类似的方式更改颜色.根据
wdg2.style.button_color = 'green'
另一种肮脏的方式是将 CSS 规则注入到笔记本中,这会影响所有 select
小部件.
%%html<风格>.widget-选择>选择{背景颜色:红色;}</风格>
自定义小部件
最终的解决方案是制作自己的
细胞 3
wdg3.mycolor = '红色'
JupyterLab 使用完全不同的框架.为了使上述自定义小部件在Lab"界面中工作,客户端代码应翻译为 TypeScript,然后在 Lab 服务器上编译、构建和安装.
The challenge:
How can you change the color for backround, font etc for widgets.SelectMultiple() and other widgets for that matter? Here's a simple setup for widgets.SelectMultiple()
Snippet / Cell 1:
# settings
%matplotlib inline
# imports
from ipywidgets import interactive, Layout
from IPython.display import clear_output
import ipywidgets as widgets
from IPython.display import display
# widget 1
wdg = widgets.SelectMultiple(
options=['Apples', 'Oranges', 'Pears'],
value=['Oranges'],
#rows=10,
description='Fruits',
disabled=False
)
display(wdg)
Widget 1:
What I've tried:
I thought i was onto something with Layout and style and was hoping the following setup with layout=Layout(width='75%', height='80px')
would let me change colors somehow as well and not only width
and height
:
Snippet / Cell 2:
wdg2 = widgets.SelectMultiple(
options=['Apples', 'Oranges', 'Pears'],
value=['Oranges'],
description='Fruits',
layout=Layout(width='75%', height='80px'),
disabled=False
)
display(wdg2)
Widget2:
But to my huge disappointment it seems that you can't change colors in a similar way. According to the ipywidgets docs, properties of the style attribute are specific to each widget type. You can get a list of the style attributes for a widget with the keys
property. And wdg2.style.keys
returns this:
['_model_module',
'_model_module_version',
'_model_name',
'_view_count',
'_view_module',
'_view_module_version',
'_view_name',
'description_width']
And since there are noe color attributes there, is it impossible to change the colors for widgets.SelectMultiple()
? For other widgets, like Button
, you'll find an attribute button_color
as well.
The short answer is: You can't do that without creating your own "custom widget".
Those attributes of style
and layout
objects are hard-coded in both the server-side and client-side libraries of ipywidgets
.
There is a dirty way to get a similar effect though, by mixing the ButtonStyle
with SelectMultiple
.
# Tested on JupyterLab 0.35.3 with Python 3.6 kernel
import ipywidgets as widgets
from ipywidgets.widgets import widget_serialization, trait_types
from traitlets import Unicode, Instance, CaselessStrEnum
class MySelectMultiple(widgets.SelectMultiple):
style=trait_types.InstanceDict(widgets.ButtonStyle).tag(sync=True, **widget_serialization)
wdg2 = MySelectMultiple(
options=['Apples', 'Oranges', 'Pears'],
value=['Oranges'],
description='Fruits',
layout=widgets.Layout(width='75%', height='80px'),
style= {'button_color':'red'},
disabled=False
)
wdg2
wdg2.style.button_color = 'green'
Another dirty way is to inject a CSS rule into the notebook which affects all select
widget.
%%html
<style>
.widget-select > select {background-color: red;}
</style>
Custom widget
The ultimate solution is to make your own custom widget. Unfortunately you need to write both server- and client side codes for it. For classical jupyter notebook, the client side code (JavaScript) can be put in a cell. But this feature may be dropped in the "next-generation" of Jupyter, i.e. JupyterLab, for security reasons.
Cell 1
%%javascript
require.undef('myselectmultiple');
define('myselectmultiple', ["@jupyter-widgets/base"], function(widgets) {
class selectmultipleView extends widgets.SelectMultipleView {
render () {
super.render();
this.mycolor_changed();
this.model.on('change:mycolor', this.mycolor_changed, this);
}
mycolor_changed () {
var mycolor = this.model.get('mycolor')
this.el.childNodes[1].style.backgroundColor = mycolor;
}
}
return {
myselectmultipleview : selectmultipleView
};
});
Cell 2
class MySelectMultipleC(widgets.SelectMultiple):
_view_name = Unicode('myselectmultipleview').tag(sync=True)
_view_module = Unicode('myselectmultiple').tag(sync=True)
_view_module_version = Unicode('0.1.0').tag(sync=True)
mycolor = Unicode('white', help='background color').tag(sync=True)
wdg3 = MySelectMultipleC(
options=['Apples', 'Oranges', 'Pears'],
value=['Oranges'],
description='Fruits',
mycolor = 'green',
disabled=False
)
wdg3
Cell 3
wdg3.mycolor = 'red'
JupyterLab uses a completely different framework. To make the above custom widget working in the "Lab" interface, the client-side code should be translated to TypeScript, and then be compiled, built and installed on the Lab server.
相关文章