ipyvuetify¶
ipyvuetify liefert Jupyter-Widgets, die auf vuetify-UI-Komponenten basieren und das Material Design von Google mit dem Vue.js-Framework implementieren.
Installation¶
$ uv add ipyvuetify
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"
],
)