如何在 ipyvuetify 中从浅色主题切换到深色主题?
how to switch from light to dark theme in ipyvuetify?
我在 Jupyter Python 环境中使用 ipyvuetify 为我的最终用户创建交互式仪表板。
我想创建一个交互式 toogle btn,将 vuitify.theme.dark
从 True
切换到 False
当我使用以下代码测试此行为时:
import ipyvuetify as v
v.theme.dark = True
#validate the selected data
v.Container(children=[
v.Btn(color='primary', children=[
v.Icon(left=True, children=[
'mdi-square'
]),
'Click me'
])
])
只有 Btn
组件的周围有深色背景,页面的其余部分保持浅色背景。
一个技巧可能是在我的 url 末尾添加 ?voila-theme=dark
,但它不再是动态的。
有没有办法同时更改 voila
和 ipyvuetify
主题?或者强制 ipyvuetify
背景占据整个屏幕?
更改 body
背景颜色
使用 Voilà(默认)实验室模板,ipyvuetify 应用程序周围的背景似乎是 HTML body
背景,因此解决方法是将 ipyvuetify 主题的背景颜色应用到body
背景。 Ipyvuetify-v.1.6.2 背景色在浅色主题中为 #fff
,在深色主题中为 #121212
(来自 vuetify.min.css-v2.2.26)。
可以通过在 HTML <style>
元素中添加内部 CSS 来修改背景颜色:
dark_bg = '.jp-Notebook {background-color: #121212}'
light_bg = '.jp-Notebook {background-color: #fff}'
def bg_switch(widget, event, data):
v.theme.dark = not v.theme.dark
css.children = [dark_bg] if v.theme.dark==True else [light_bg]
btn = v.Btn(children=[v.Icon(children=['mdi-theme-light-dark'])])
btn.on_event('click',bg_switch)
css = v.Html(tag='style', children=[dark_bg] if v.theme.dark==True else [light_bg])
v.Container(children=[css,btn])
另一种解决方案是通过设置 HTML DOM 样式 backgroundColor 属性 of body
:
添加内联 CSS
class BtnTheme(v.VuetifyTemplate):
dark = traitlets.Bool(v.theme.dark).tag(sync=True)
template = traitlets.Unicode('''
<v-btn icon @click="switchTheme">
<v-icon>mdi-theme-light-dark</v-icon>
</v-btn>
<script> {created() {this.updateBackground()},
methods: {
switchTheme() {
this.dark = !this.dark;
this.updateBackground()
},
updateBackground() {
document.body.style.backgroundColor = this.dark ? '#121212' : '#fff'
}
}}
</script>''').tag(sync=True)
btn = BtnTheme()
ipywidgets.jslink((btn, 'dark'), (v.theme, 'dark'))
v.Container(children=[btn])
在上述解决方案中,主题按钮使用 v.theme.dark
的值初始化,即 False
除非在应用程序代码中早些时候设置为 True
。另外,主题按钮可以初始化为Voilà(实验室模板)主题:
- 通过检查查询参数:
v.theme.dark = (os.environ.get('QUERY_STRING', '').find('dark') != -1)
- 或者通过在
created()
函数的开头检查 theme-dark
在 body
类: 中的存在
if (document.body.classList.contains('theme-dark')) {this.dark = true}
在背景颜色未知的情况下,可以通过两个虚拟元素检测这两种颜色,每个虚拟元素都使用以下两个主题之一设置样式:
class BtnTheme(v.VuetifyTemplate):
dark = traitlets.Bool(v.theme.dark).tag(sync=True)
v_dark_bg = traitlets.Unicode('').tag(sync=True)
v_light_bg = traitlets.Unicode('').tag(sync=True)
template = traitlets.Unicode('''
<v-btn icon @click="switchTheme">
<v-icon>mdi-theme-light-dark</v-icon>
<div class="v-application theme--dark" id="v-dark-style"></div>
<div class="v-application theme--light" id="v-light-style"></div>
</v-btn>
<script> {
mounted() {
this.v_dark_bg = getComputedStyle(document.getElementById("v-dark-style")).backgroundColor
this.v_light_bg = getComputedStyle(document.getElementById("v-light-style")).backgroundColor
if (document.body.classList.contains('theme-dark')) {this.dark = true}
this.updateBackground()
},
methods: {
switchTheme() {
this.dark = !this.dark
this.updateBackground()
},
updateBackground() {
document.body.style.backgroundColor = this.dark ? this.v_dark_bg : this.v_light_bg
}
}
}
</script>''').tag(sync=True)
一个技巧是添加一个不透明的 Overlay 组件作为背景(z-index=-1
)并在切换 ipyvuetify 主题时改变它的颜色:
import ipyvuetify as v
dark_bg = '#121212'
light_bg = '#fff'
bg = v.Overlay(
color=dark_bg if v.theme.dark==True else light_bg,
opacity=1,
style_='transition:unset',
z_index=-1
)
def bg_switch(widget, event, data):
v.theme.dark = not v.theme.dark
bg.color = dark_bg if v.theme.dark==True else light_bg
btn = v.Btn(children=[v.Icon(children=['mdi-theme-light-dark'])])
btn.on_event('click', bg_switch)
v.Container(children=[bg, btn])
不需要 JS 代码。颜色定义来自 vuetify.min.css
(ipyvuetify 1.6.2 使用的 v2.2.26):#fff
浅色主题和 #121212
深色主题。
我在 Jupyter Python 环境中使用 ipyvuetify 为我的最终用户创建交互式仪表板。
我想创建一个交互式 toogle btn,将 vuitify.theme.dark
从 True
切换到 False
当我使用以下代码测试此行为时:
import ipyvuetify as v
v.theme.dark = True
#validate the selected data
v.Container(children=[
v.Btn(color='primary', children=[
v.Icon(left=True, children=[
'mdi-square'
]),
'Click me'
])
])
只有 Btn
组件的周围有深色背景,页面的其余部分保持浅色背景。
一个技巧可能是在我的 url 末尾添加 ?voila-theme=dark
,但它不再是动态的。
有没有办法同时更改 voila
和 ipyvuetify
主题?或者强制 ipyvuetify
背景占据整个屏幕?
更改 body
背景颜色
使用 Voilà(默认)实验室模板,ipyvuetify 应用程序周围的背景似乎是 HTML body
背景,因此解决方法是将 ipyvuetify 主题的背景颜色应用到body
背景。 Ipyvuetify-v.1.6.2 背景色在浅色主题中为 #fff
,在深色主题中为 #121212
(来自 vuetify.min.css-v2.2.26)。
可以通过在 HTML <style>
元素中添加内部 CSS 来修改背景颜色:
dark_bg = '.jp-Notebook {background-color: #121212}'
light_bg = '.jp-Notebook {background-color: #fff}'
def bg_switch(widget, event, data):
v.theme.dark = not v.theme.dark
css.children = [dark_bg] if v.theme.dark==True else [light_bg]
btn = v.Btn(children=[v.Icon(children=['mdi-theme-light-dark'])])
btn.on_event('click',bg_switch)
css = v.Html(tag='style', children=[dark_bg] if v.theme.dark==True else [light_bg])
v.Container(children=[css,btn])
另一种解决方案是通过设置 HTML DOM 样式 backgroundColor 属性 of body
:
class BtnTheme(v.VuetifyTemplate):
dark = traitlets.Bool(v.theme.dark).tag(sync=True)
template = traitlets.Unicode('''
<v-btn icon @click="switchTheme">
<v-icon>mdi-theme-light-dark</v-icon>
</v-btn>
<script> {created() {this.updateBackground()},
methods: {
switchTheme() {
this.dark = !this.dark;
this.updateBackground()
},
updateBackground() {
document.body.style.backgroundColor = this.dark ? '#121212' : '#fff'
}
}}
</script>''').tag(sync=True)
btn = BtnTheme()
ipywidgets.jslink((btn, 'dark'), (v.theme, 'dark'))
v.Container(children=[btn])
在上述解决方案中,主题按钮使用 v.theme.dark
的值初始化,即 False
除非在应用程序代码中早些时候设置为 True
。另外,主题按钮可以初始化为Voilà(实验室模板)主题:
- 通过检查查询参数:
v.theme.dark = (os.environ.get('QUERY_STRING', '').find('dark') != -1)
- 或者通过在
created()
函数的开头检查theme-dark
在body
类: 中的存在
if (document.body.classList.contains('theme-dark')) {this.dark = true}
在背景颜色未知的情况下,可以通过两个虚拟元素检测这两种颜色,每个虚拟元素都使用以下两个主题之一设置样式:
class BtnTheme(v.VuetifyTemplate):
dark = traitlets.Bool(v.theme.dark).tag(sync=True)
v_dark_bg = traitlets.Unicode('').tag(sync=True)
v_light_bg = traitlets.Unicode('').tag(sync=True)
template = traitlets.Unicode('''
<v-btn icon @click="switchTheme">
<v-icon>mdi-theme-light-dark</v-icon>
<div class="v-application theme--dark" id="v-dark-style"></div>
<div class="v-application theme--light" id="v-light-style"></div>
</v-btn>
<script> {
mounted() {
this.v_dark_bg = getComputedStyle(document.getElementById("v-dark-style")).backgroundColor
this.v_light_bg = getComputedStyle(document.getElementById("v-light-style")).backgroundColor
if (document.body.classList.contains('theme-dark')) {this.dark = true}
this.updateBackground()
},
methods: {
switchTheme() {
this.dark = !this.dark
this.updateBackground()
},
updateBackground() {
document.body.style.backgroundColor = this.dark ? this.v_dark_bg : this.v_light_bg
}
}
}
</script>''').tag(sync=True)
一个技巧是添加一个不透明的 Overlay 组件作为背景(z-index=-1
)并在切换 ipyvuetify 主题时改变它的颜色:
import ipyvuetify as v
dark_bg = '#121212'
light_bg = '#fff'
bg = v.Overlay(
color=dark_bg if v.theme.dark==True else light_bg,
opacity=1,
style_='transition:unset',
z_index=-1
)
def bg_switch(widget, event, data):
v.theme.dark = not v.theme.dark
bg.color = dark_bg if v.theme.dark==True else light_bg
btn = v.Btn(children=[v.Icon(children=['mdi-theme-light-dark'])])
btn.on_event('click', bg_switch)
v.Container(children=[bg, btn])
不需要 JS 代码。颜色定义来自 vuetify.min.css
(ipyvuetify 1.6.2 使用的 v2.2.26):#fff
浅色主题和 #121212
深色主题。