Jupyter:如何更改SelectMultiple()之类的小部件的颜色?

时间:2019-02-12 08:25:52

标签: python widget jupyter-notebook ipython jupyter

挑战:

如何更改widgets.SelectMultiple()和其他小部件的背景颜色,字体等的颜色?这是widgets.SelectMultiple()

的简单设置

代码段/单元格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)

小部件1:

enter image description here

我尝试过的事情:

我认为我正在使用Layoutstyle做某事,并希望通过layout=Layout(width='75%', height='80px')进行以下设置也可以让我以某种方式更改颜色,而不仅仅是widthheight

代码段/单元格2:

wdg2 = widgets.SelectMultiple(
    options=['Apples', 'Oranges', 'Pears'],
    value=['Oranges'],
    description='Fruits',
    layout=Layout(width='75%', height='80px'),
    disabled=False
)

display(wdg2)

小部件2:

enter image description here

但是令我非常失望的是,您似乎无法以类似的方式更改颜色。根据{{​​3}},style属性的属性特定于每种小部件类型。您可以使用keys属性获取小部件的样式属性列表。 wdg2.style.keys返回:

['_model_module',
 '_model_module_version',
 '_model_name',
 '_view_count',
 '_view_module',
 '_view_module_version',
 '_view_name',
 'description_width']

并且由于那里没有颜色属性,因此无法更改widgets.SelectMultiple()的颜色吗?对于其他小部件,例如Button,您还将找到属性button_color

3 个答案:

答案 0 :(得分:1)

简短的答案是:如果不创建自己的"custom widget",您将无法做到这一点。 stylelayout对象的那些属性在ipywidgets的{​​{3}}和server-side库中都进行了硬编码。

通过将ButtonStyleSelectMultiple混合在一起,有一种肮脏的方式获得类似的效果。

# 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

client-side

wdg2.style.button_color = 'green'

wdg2_red

另一种肮脏的方法是将CSS规则注入笔记本中,从而影响所有select小部件。

%%html
<style>
    .widget-select > select {background-color: red;}   
</style>

wdg2_green

自定义小部件

最终的解决方案是制作自己的enter image description here。 不幸的是,您需要为此编写服务器和客户端代码。 对于经典的jupyter笔记本,可以将客户端代码(JavaScript)放在单元格中。 但是出于安全原因,可以在Jupyter的“下一代”(即custom widget)中删除此功能。

单元格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
    };
});

单元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

JupyterLab

单元3

wdg3.mycolor = 'red'

enter image description here

JupyterLab使用完全不同的框架。为了使上述自定义窗口小部件在“实验室”界面中工作,客户端代码应转换为TypeScript,然后在实验室服务器上进行编译,构建和安装。

答案 1 :(得分:1)

晚了聚会,但这是我的简单解决方案,用于将颜色用于编码简单的两个(或多个)状态的情况: use unicode!

样本:

enter image description here

代码(在python 3 ... :)中)

from ipywidgets import interactive, Layout
from IPython.display import clear_output
import ipywidgets as widgets
from IPython.display import display

c_base = int("1F534",base=16)
# widget 1
options=['Apples', 'Oranges', 'Pears']
state = [False,True,True]
colored_options = ['{} {}'.format(chr(c_base+s), o) for s,o in zip(state,options)]
wdg = widgets.SelectMultiple(
    options=colored_options,
    description='Fruits',
    disabled=False
)

display(wdg)

如果需要更多颜色,请尝试使用此代码进行搜索...:

for i in range (10):
    ii = int('0x1f7e0',base=16)+i
    print('{:>15}'.format('[{}: {}] '.format(hex(ii),chr(ii))),end='')
    if i%7==6:
        print()

enter image description here

答案 2 :(得分:1)

jp_proxy_widget 使您可以轻松地在小部件中执行 HTML5/javascript 中可以执行的任何操作。例如这里是一个彩色多选:

colorized multiple select jupyter widget

在此处查找:https://github.com/AaronWatters/jp_proxy_widget