ipyvuetify
¶
ipyvuetify liefert Jupyter-Widgets, die auf vuetify-UI-Komponenten basieren und das Material Design von Google mit dem Vue.js-Framework implementieren.
Installation¶
$ pipenv install ipyvuetify
Installing ipyvuetify…
…
$ pipenv run jupyter nbextension enable --py --sys-prefix ipyvuetify
Enabling notebook extension jupyter-vuetify/extension...
- Validating: OK
Beispiele¶
Importe¶
[1]:
from threading import Timer
import ipyvuetify as v
import ipywidgets
from traitlets import Any, List, Unicode
Menü¶
[2]:
def on_menu_click(widget, event, data):
if len(layout.children) == 1:
layout.children = layout.children + [info]
info.children = [f"Item {items.index(widget)+1} clicked"]
items = [
v.ListItem(children=[v.ListItemTitle(children=[f"Item {i}"])])
for i in range(1, 5)
]
for item in items:
item.on_event("click", on_menu_click)
menu = v.Menu(
offset_y=True,
v_slots=[
{
"name": "activator",
"variable": "menuData",
"children": v.Btn(
v_on="menuData.on",
class_="ma-2",
color="primary",
children=[
"menu",
v.Icon(right=True, children=["arrow_drop_down"]),
],
),
}
],
children=[v.List(children=items)],
)
info = v.Chip(class_="ma-2")
layout = v.Layout(children=[menu])
layout
Buttons¶
[3]:
v.Layout(
children=[
v.Btn(color="primary", children=["primary"]),
v.Btn(color="error", children=["error"]),
v.Btn(disabled=True, children=["disabled"]),
v.Btn(children=["reset"]),
]
)v.Layout(
children=[
v.Btn(color="primary", flat=True, children=["flat"]),
v.Btn(color="primary", round=True, children=["round"]),
v.Btn(
color="primary",
flat=True,
icon=True,
children=[v.Icon(children=["thumb_up"])],
),
v.Btn(color="primary", outline=True, children=["outline"]),
v.Btn(
color="primary",
fab=True,
large=True,
children=[v.Icon(children=["edit"])],
),
]
)
[4]:
v.Layout(
children=[
v.Btn(color="primary", flat=True, children=["flat"]),
v.Btn(color="primary", round=True, children=["round"]),
v.Btn(
color="primary",
flat=True,
icon=True,
children=[v.Icon(children=["thumb_up"])],
),
v.Btn(color="primary", outline=True, children=["outline"]),
v.Btn(
color="primary",
fab=True,
large=True,
children=[v.Icon(children=["edit"])],
),
]
)
[5]:
def toggleLoading():
button2.loading = not button2.loading
button2.disabled = button2.loading
def on_loader_click(*args):
toggleLoading()
Timer(2.0, toggleLoading).start()
button2 = v.Btn(loading=False, children=["loader"])
button2.on_event("click", on_loader_click)
v.Layout(children=[button2])
[6]:
toggle_single = v.BtnToggle(
v_model=2,
class_="mr-3",
children=[
v.Btn(flat=True, children=[v.Icon(children=["format_align_left"])]),
v.Btn(flat=True, children=[v.Icon(children=["format_align_center"])]),
v.Btn(flat=True, children=[v.Icon(children=["format_align_right"])]),
v.Btn(flat=True, children=[v.Icon(children=["format_align_justify"])]),
],
)
toggle_multi = v.BtnToggle(
v_model=[0, 2],
multiple=True,
children=[
v.Btn(flat=True, children=[v.Icon(children=["format_bold"])]),
v.Btn(flat=True, children=[v.Icon(children=["format_italic"])]),
v.Btn(flat=True, children=[v.Icon(children=["format_underline"])]),
v.Btn(flat=True, children=[v.Icon(children=["format_color_fill"])]),
],
)
v.Layout(
children=[
toggle_single,
toggle_multi,
]
)
[7]:
v.Layout(
children=[
v.Btn(
color="primary",
children=[
v.Icon(left=True, children=["fingerprint"]),
"Icon left",
],
),
v.Btn(
color="primary",
children=[
"Icon right",
v.Icon(right=True, children=["fingerprint"]),
],
),
v.Tooltip(
bottom=True,
children=[
v.Btn(slot="activator", color="primary", children=["tooltip"]),
"Insert tooltip text here",
],
),
]
[8]:
lorum_ipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
v.Layout(
children=[
v.Dialog(
width="500",
v_slots=[
{
"name": "activator",
"variable": "x",
"children": v.Btn(
v_on="x.on",
color="success",
dark=True,
children=["Open dialog"],
),
}
],
children=[
v.Card(
children=[
v.CardTitle(
class_="headline gray lighten-2",
primary_title=True,
children=["Lorem ipsum"],
),
v.CardText(children=[lorum_ipsum]),
]
)
],
)
]
)
Slider¶
[9]:
slider = v.Slider(v_model=25)
slider2 = v.Slider(thumb_label=True, v_model=25)
slider3 = v.Slider(thumb_label="always", v_model=25)
ipywidgets.jslink((slider, "v_model"), (slider2, "v_model"))
v.Container(
children=[
slider,
slider2,
]
)
Reiter¶
[10]:
tab_list = [v.Tab(children=["Tab " + str(i)]) for i in range(1, 4)]
content_list = [v.TabItem(children=[lorum_ipsum]) for i in range(1, 4)]
tabs = v.Tabs(v_model=1, children=tab_list + content_list)
tabs
Akkordeon¶
[11]:
vepc1 = v.ExpansionPanel(
children=[
v.ExpansionPanelHeader(children=["item1"]),
v.ExpansionPanelContent(children=["First Text"]),
]
)
vepc2 = v.ExpansionPanel(
children=[
v.ExpansionPanelHeader(children=["item2"]),
v.ExpansionPanelContent(children=["Second Text"]),
]
)
vep = v.ExpansionPanels(children=[vepc1, vepc2])
vl = v.Layout(class_="pa-4", children=[vep])
vl
In der Vuetify-Dokumentation könnt ihr nach allen verfügbaren Komponenten und Attributen suchen. Dabei orientiert sich Ipyvuetify an der Syntax von Vue.js- und Vuetify, aber es gibt auch einige Unterschiede:
Beschreibung |
Vuetify |
ipyvuetify |
---|---|---|
Komponentennamen werden in CamelCase geschrieben und der |
|
|
Untergeordnete Komponenten und Text werden im Traitlet für untergeordnete Elemente definiert |
|
|
Flag-Attribute erfordern einen booleschen Wert |
|
|
Attribute sind snake_case |
|
|
Das Attribut |
|
|
Der Geltungsbereich von |
|
|
Event-Listener werden mit |
|
|
Reguläre HTML-Tags können mit der Klasse |
|
|
Den Attributen |
|
|
VuetifyTemplate
¶
Eine engere Übereinstimmung mit der Vue/Vuetify-API erhaltet ihr mit VuetifyTemplate
. Hierfür erstellt ihr eine Unterklasse von VuetifyTemplate
und definiert eigene Traitlets. Auf die Traitlets kann über das Template zugegriffen werden, so als befänden sie sich in einem Vue-Modell. Methoden können mit dem Präfix vue_
definiert werden, z.B. def vue_button_click(self, data)
, das dann mit @click="button_click(e)"
aufgerufen werden kann. Im Folgenden zeige ich Euch eine Tabelle
mit Suche, Sortierung und Zeilenanzahl:
[12]:
import json
import ipyvuetify as v
import pandas as pd
import traitlets
class PandasDataFrame(v.VuetifyTemplate):
"""
Vuetify DataTable rendering of a pandas DataFrame
Args:
data (DataFrame) - the data to render
title (str) - optional title
"""
headers = traitlets.List([]).tag(sync=True, allow_null=True)
items = traitlets.List([]).tag(sync=True, allow_null=True)
search = traitlets.Unicode("").tag(sync=True)
title = traitlets.Unicode("DataFrame").tag(sync=True)
index_col = traitlets.Unicode("").tag(sync=True)
template = traitlets.Unicode(
"""
<template>
<v-card>
<v-card-title>
<span class="title font-weight-bold">{{ title }}</span>
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="search"
label="Search ..."
single-line
hide-details
></v-text-field>
</v-card-title>
<v-data-table
:headers="headers"
:items="items"
:search="search"
:item-key="index_col"
:rows-per-page-items="[25, 50, 250, 500]"
>
<template v-slot:no-data>
<v-alert :value="true" color="error" icon="warning">
Sorry, nothing to display here :(
</v-alert>
</template>
<template v-slot:no-results>
<v-alert :value="true" color="error" icon="warning">
Your search for "{{ search }}" found no results.
</v-alert>
</template>
<template v-slot:items="rows">
<td v-for="(element, label, index) in rows.item"
@click=cell_click(element)
>
{{ element }}
</td>
</template>
</v-data-table>
</v-card>
</template>
"""
).tag(sync=True)
def __init__(self, *args, data=pd.DataFrame(), title=None, **kwargs):
super().__init__(*args, **kwargs)
data = data.reset_index()
self.index_col = data.columns[0]
headers = [{"text": col, "value": col} for col in data.columns]
headers[0].update({"align": "left", "sortable": True})
self.headers = headers
self.items = json.loads(data.to_json(orient="records"))
if title is not None:
self.title = title
iris = pd.read_csv(
"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv"
)
test = PandasDataFrame(data=iris, title="Iris")
test
[13]:
v.Banner(
single_line=True,
v_slots=[
{"name": "icon", "children": v.Icon(children=["thumb_up"])},
{
"name": "actions",
"children": v.Btn(
text=True, color="deep-purple accent-4", children=["Action"]
),
},
],
children=[
"One line message text string with two actions on tablet / Desktop"
],
)