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

ves*_*and 7 python widget ipython jupyter jupyter-notebook

挑战:

您如何更改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)
Run Code Online (Sandbox Code Playgroud)

小部件 1:

在此处输入图片说明

我试过的:

我以为我对布局样式感兴趣,并希望以下设置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)
Run Code Online (Sandbox Code Playgroud)

小部件2:

在此处输入图片说明

但令我非常失望的是,您似乎无法以类似的方式改变颜色。根据ipywidgets 文档, style 属性的属性特定于每个小部件类型。您可以使用该属性获取小部件的样式属性列表keys。并wdg2.style.keys返回:

['_model_module',
 '_model_module_version',
 '_model_name',
 '_view_count',
 '_view_module',
 '_view_module_version',
 '_view_name',
 'description_width']
Run Code Online (Sandbox Code Playgroud)

并且由于那里没有颜色属性,是否不可能更改颜色widgets.SelectMultiple()?对于其他小部件,例如Button,您也会找到一个属性button_color

ntg*_*ntg 7

迟到了,但这是我的简单解决方案,对于颜色将用于对简单的两个(或多个)状态进行编码的情况:使用 unicode!

样本:

在此输入图像描述

代码(在 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)
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


gdl*_*lmx 6

简短的回答是:如果不创建自己的“自定义小部件”,您就无法做到这一点。这些属性stylelayout对象是硬编码在两个服务器端客户端的库ipywidgets

但是,通过将ButtonStyle与混合,有一种肮脏的方法可以获得类似的效果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
Run Code Online (Sandbox Code Playgroud)

wdg2_red

wdg2.style.button_color = 'green'
Run Code Online (Sandbox Code Playgroud)

wdg2_green

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

%%html
<style>
    .widget-select > select {background-color: red;}   
</style>
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

自定义小部件

最终的解决方案是制作自己的自定义小部件。不幸的是,您需要为它编写服务器端和客户端代码。对于经典的 jupyter notebook,客户端代码 (JavaScript) 可以放在一个单元格中。但是出于安全原因,此功能可能会在 Jupyter 的“下一代”中删除,即 JupyterLab

单元格 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
    };
});
Run Code Online (Sandbox Code Playgroud)

单元格 2

%%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
    };
});
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

单元格 3

wdg3.mycolor = 'red'
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

  • 最好在你的 notebook 中包含一些 CSS 规则,并为 `&lt;select&gt;` 和 `&lt;option&gt;` 元素设置相应的类。您可以在其他帖子中找到 CSS 和选择示例 [one](/sf/ask/1108108081/)。 (2认同)