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.