【问题标题】:Jupyter: How to change color for widgets like SelectMultiple()?Jupyter:如何更改 SelectMultiple() 等小部件的颜色?
【发布时间】:2019-02-12 08:25:52
【问题描述】:

挑战:

如何更改 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:

我的尝试:

我以为我对Layout 和style 有所了解,并希望layout=Layout(width='75%', height='80px') 的以下设置也能让我以某种方式改变颜色,而不仅仅是width 和height:

片段/单元格 2:

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

display(wdg2)

小部件2:

但令我非常失望的是,您似乎无法以类似的方式更改颜色。根据ipywidgets docs,样式属性的属性特定于每个小部件类型。您可以使用 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。

【问题讨论】:

    标签: python widget jupyter-notebook ipython jupyter


    【解决方案1】:

    简短的回答是:如果不创建自己的"custom widget",就无法做到这一点。 style 和 layout 对象的这些属性在 ipywidgets 的 server-side 和 client-side 库中都是硬编码的。

    不过,有一种肮脏的方法可以获得类似的效果,将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
    

    wdg2.style.button_color = 'green'
    

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

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

    自定义小部件

    最终的解决方案是制作自己的custom widget。 不幸的是,您需要为它编写服务器端和客户端代码。 对于经典的 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
        };
    });
    

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

    细胞 3

    wdg3.mycolor = 'red'
    

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

    【讨论】:

    • 感谢您的回答!这很棒!这可能只是我缺乏谷歌搜索专业知识,但这似乎不可能找到!可以邀请你聊一些小的后续问题吗?
    • 我已经接受了您的回答,但是您知道如何更改选择指示器的字体、字体大小和颜色吗?
    • 您可以在javascript中的render()函数中添加更多行,例如this.el.childNodes[1].style.fontSize = '12px'。
    • 最好在你的 notebook 中加入一些 CSS 规则,并将对应的类设置为 &lt;select&gt; 和 &lt;option&gt; 元素。您可以在 one 等其他帖子中找到 CSS 示例并进行选择。
    • 酷!谢谢!
    【解决方案2】:

    聚会迟到了,但这是我的简单解决方案,对于将使用颜色来编码简单的两个(或多个)状态的情况:use 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)
    

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

    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()
    

    【讨论】:

    • 我喜欢您巧妙的解决方案,虽然它并没有真正回答最初的问题,但它启发了我使用 Unicode 表情符号对各个行进行颜色编码。请注意,在 Windows 10 中,您可以使用 Win+.(dot) 热键打开表情符号菜单来搜索颜色⚪⚫??????? :)
    【解决方案3】:

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

    在这里找到它:https://github.com/AaronWatters/jp_proxy_widget

    【讨论】:

      猜你喜欢
      • 2018-05-04
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 2021-12-23
      相关资源
      最近更新 更多