Benutzerdefiniertes Widget¶
Das Widget-Framework basiert auf dem Comms-Framework, das dem Kernel ermöglicht, JSON an das Frontend zu senden und zu empfangen. Um nun ein benutzerdefiniertes Widget zu erstellen, muss das Widget sowohl im Browser als auch im Python-Kernel definiert werden.
Weitere Informationen zum Comms-Framework erhaltet ihr im Low Level Widget Explanation.
Python-Kernel¶
DOMWidget¶
Um ein Widget zu definieren, muss es von der Basisklasse Widget
oder DOMWidget
erben. Wenn das Widget im Jupyter-Notebook angezeigt werden soll, sollte euer Widget von DOMWidget
erben. Dabei erbt Die DOMWidget
-Klasse selbst von der Widget
-Klasse.
_view_name
¶
Durch die Übernahme von DOMWidget
wird dem Widget-Framework nicht mitgeteilt, welches Frontend-Widget mit dem Backend-Widget verknüpft werden soll.
Stattdessen müsst ihr dies selbst angeben durch eines der folgenden Attribute:
_view_name
_view_module
_view_module_version
und gegebenenfalls
_model_name
_model_module
[1]:
import ipywidgets as widgets
from traitlets import Unicode, validate
class HelloWidget(widgets.DOMWidget):
_view_name = Unicode("HelloView").tag(sync=True)
_view_module = Unicode("hello").tag(sync=True)
_view_module_version = Unicode("0.1.0").tag(sync=True)
sync=True
-Traitlets¶
Traitlets ist ein Framework, mit dem Python-Klassen Attribute mit Typprüfung, dynamisch berechneten Standardwerten und Callbacks bei Änderung haben können. Das sync=True
- Keyword-Argument weist das Widget-Framework an, den Wert mit dem Browser zu synchronisieren; ohne würde der Browser nichts von _view_name
oder _view_module
erfahren.
Frontend (JavaScript)¶
Models und Views¶
Das Frontend des IPython-Widget-Frameworks hängt stark von Backbone.js ab. Backbone.js ist ein MVC-Framework (Model View Controller), das im Backend definierte Widgets automatisch mit generischen Backbone.js-Modellen im Frontend synchronisiert: das vorher definierte _view_name
-Merkmal wird vom Widget-Framework verwendet, um die entsprechende Backbone.js-View zu erstellen und diese mit dem Model
zu verknüpfen.
@jupyter-widgets/base
importieren¶
Ihr müsst zuerst das @jupyter-widgets/base
-Modul mit der define
-Methode von RequireJS importieren:
[2]:
%%javascript
define('hello', ["@jupyter-widgets/base"], function(widgets) {
});
View definieren¶
Als nächstes definieren wir die Widget-View-Klasse wobei wir von DOMWidgetView
mit der .extend
-Methode erben.
[3]:
%%javascript
require.undef('hello');
define('hello', ["@jupyter-widgets/base"], function(widgets) {
// Define the HelloView
var HelloView = widgets.DOMWidgetView.extend({});
return {
HelloView: HelloView
}
});
render
-Methode¶
Zum Schluss müssen wir noch die Basismethode render
überschreiben um eine benutzerdefinierte Rendering-Logik zu definieren. Ein Handle auf das Standard-DOM-Element des Widgets kann mit this.el
aufgerufen werden. Die el
-Eigenschaft ist das DOM-Element, das der Ansicht zugeordnet ist.
[4]:
%%javascript
require.undef('hello');
define('hello', ["@jupyter-widgets/base"], function(widgets) {
var HelloView = widgets.DOMWidgetView.extend({
// Render the view.
render: function() {
this.el.textContent = 'Hello World!';
},
});
return {
HelloView: HelloView
};
});
Test¶
Das Widget lässt sich jetzt wie jedes andere Widget anzeigen mit
[5]:
HelloWidget()
Stateful Widget¶
Mit dem obigen Beispiel könnt ihr noch nicht viel tun. Um dies zu ändern, müsst ihr das Widget stateful machen. Anstelle einer statischen Hello World!-Meldung soll eine vom Backend festgelegter String angezeigt werden. Hierzu wird zunächst ein neues Traitlet hinzugefügt. Verwendet hierbei den Namen von value
, um mit dem Rest des Widget-Frameworks konsistent zu bleiben und die Verwendung eures Widgets mit Interaktion zu ermöglichen.
Jupyter Widgets aus einem Template erstellen¶
Mit widget-cookiecutter ist ein Cookiecutter-Template verfügbar. Es enthält eine Implementierung für ein Platzhalter-Widget Hello World. Darüberhinaus erleichtert es euch das Packen und Verteilen eurer Jupyter Widgets.