Skript-Schnittstelle

Die Skript-Schnittstelle im Actions-System bietet eine einfache Möglichkeit, interaktive Benutzeroberflächen für jedes Programm zu erstellen. Du kannst sogar einfache Benutzeroberflächen erstellen, ohne eine einzige Zeile Skript zu schreiben. Mit zusätzlichen Skripten kannst du jedoch die eingegebenen Daten validieren und sogar eine interaktive Rückmeldung des laufenden Programms geben.

Um die Skript-Schnittstelle zu aktivieren, musst du den Wert der Aktionsschnittstelle auf uiscript setzen. In der folgenden Box siehst du zwei Beispiele, wie eine Aktion mit der uiscript-Schnittstelle konfiguriert wird.

Zwei Beispiele zur Einrichtung der uiscript-Schnittstelle
<Module name="Application">
    ...
    <List name="actionList">
        <ListEntry>
            <Value name="actionName">example1</Value>
            ...
            <Value name="interface">uiscript;ui=example.ui</Value>
            ...
        </ListEntry>
        <ListEntry>
            <Value name="actionName">example2</Value>
            ...
            <Value name=”interface”>uiscript;script=example.js;ui=example.ui</Value>
            ...
        </ListEntry>
        ...
    </List>
    ...
</Module>

Die Option ui ist erforderlich. Sie gibt den Dateinamen für die Benutzeroberflächendeklaration an. Die Option script ist optional und gibt den Dateinamen einer Skriptdatei an, welche zusammen mit der Benutzeroberflächenbeschreibung verwendet wird.

Beide Dateinamen dürfen keinen absoluten oder relativen Pfad enthalten. Die Dateien müssen in einem der Unterverzeichnisse abgelegt werden, die in der Liste uiScriptDirectories konfiguriert sind (siehe Die Liste uiScriptDirectories). Für das obige Beispiel könnte die Dateistruktur wie folgt aussehen:

c:/
└── actions
    └── uiscripts
        ├── example.ui
        └── example.js

Wo die Liste uiScriptDirectories in der Konfiguration so gesetzt ist:

<Module name="Application">
    ...
    <List name="uiScriptDirectories">
        <Value>c:/actions/uiscripts</Value>
    </List>
</Module>

Die Dateiendung der Schnittstellendeklaration muss .ui und die Dateiendung für die Skriptdatei muss .js (für JavaScript) sein.

Die beiden Dateitypen

Die nächsten zwei Abschnitte beschreiben die zwei Dateitypen, die zur Konfiguration eines benutzerdefinierten grafischen Oberfläche verwendet werden.

Die Schnittstellendeklaration

Die Schnittstellendeklaration ist eine XML-Datei, die mit dem Qt Designer aus der Qt-Bibliothek Version fünf oder neuer erstellt werden kann. Sie enthält die Beschreibung der Benutzeroberfläche mit allen Elementen und Elementnamen.

Um den Qt Designer zu bekommen, kannst du die neueste Version des Open-Source Qt SDK kostenlos herunterladen und installieren. Der Designer ist Teil jeder SDK-Installation. Die ausführbare Datei heißt designer.exe und du findest sie im bin-Unterverzeichnis. Du kannst das Open-Source-SDK von folgender Adresse herunterladen: https://www.qt.io/download-open-source

Damit die Skript-Benutzeroberfläche funktioniert, erstelle im Designer ein „Widget“. „Fenster“ oder „Dialoge“ funktionieren nicht.

Die Skriptdatei

Die Skriptdatei ist eine UTF-8-kodierte Datei, die ein ECMA-Skript für die interaktiven Teile der Benutzeroberfläche enthält.

In diesem Skript weist du eine Reihe von Callback-Funktionen dem actions-Objekt zu. Diese werden aufgerufen, wenn die Schnittstelle vom Client angezeigt wird. Mehr Details zu diesen Funktionen findest du später in diesem Kapitel.

Wie es funktioniert, Schritt für Schritt

  • Wenn ein Benutzer auf eine Aktion klickt, die auf uiscript basiert, fordert der Client die Benutzeroberflächendeklaration und optional die Skriptdatei vom Server an.

  • Der Server sucht in den konfigurierten Verzeichnissen nach diesen Dateien und sendet den Inhalt der Dateien zurück zum Client. Dies geschieht jedes Mal und die Inhalte werden nicht zwischengespeichert. (So kannst du deine Skripte einfach durch Bearbeiten der Dateien entwickeln, ohne den Server neu starten zu müssen.)

  • Der Client erstellt die Benutzeroberfläche aus der Benutzeroberflächendefinition und führt das vom Benutzer bereitgestellte Skript aus. Das Skript darf zu diesem Zeitpunkt keinen funktionalen Code ausführen, es sollte lediglich die Callback-Funktionen initialisieren.

  • Bei Erfolg ruft der Client die onInit-Funktion aus dem Skript auf, um dem Skript die Möglichkeit zu geben, Verbindungen oder andere Dinge auf der Benutzeroberfläche zu initialisieren.

  • Der Client zeigt dem Benutzer den individuellen Dialog an.

  • Wenn der Benutzer auf den :guilabel`Ok`-Button klickt, prüft der Client, ob eine onExecute-Funktion zugewiesen ist. In diesem Fall wird diese Methode aufgerufen. Andernfalls startet der Client den Prozess wie gewohnt (lokal oder remote).

  • Für jede Zeile der Prozessausgabe ruft der Client die onProcessOutput-Funktion auf, sofern eine solche zugewiesen ist.

  • Nachdem der Prozess abgeschlossen ist, wird der Ausführungsbutton vom Dialog entfernt und der Cancel-Button wird in Close umbenannt. Die onFinished-Funktion wird aufgerufen. Wenn keine solche Funktion zugewiesen ist, schließt der Client die benutzerdefinierte Benutzeroberfläche und eine Konsole, falls sie angezeigt wurde.

Die Benutzeroberfläche

Du kannst eine beliebige Benutzeroberfläche für deine Aktion entwerfen, die eine beliebige Anzahl von Elementen enthält. Um die Elemente aus einem Skript zu nutzen oder den Text von Elementen zu verwenden, solltest du den Elementen der Benutzeroberfläche eindeutige Namen im Qt Designer geben.

Die Benutzeroberfläche, die du mit dem Qt Designer erstellst, wird in den Dialog eingebettet, wie in der folgenden Abbildung gezeigt.

Eine Illustration zeigt ein benutzerdefiniertes Benutzeroberflächenfenster, in dem der mittlere Bereich als "Benutzerdefinierte UI-Bereich" gekennzeichnet ist.

In dieser Illustration wird der gekennzeichnete Bereich mit deiner benutzerdefinierten Oberfläche ausgefüllt. Es ist wichtig, dass du deine Benutzeroberfläche im Designer als „Widget“ gestaltest. Du darfst kein Dialogfenster oder Fenster erstellen.

Der Ok-Button ist standardmäßig aktiviert. Du kannst ihn über ein Interfaceskript deaktivieren oder umbenennen. Dies wird in der obigen Illustration demonstriert, wo der Ok-Button in Start umbenannt und deaktiviert wurde.

Textausgaben von QLineEdit, QTextEdit, QPlainTextEdit und der Wert von QSpinBox sind automatisch verfügbar mit dem {ui:<name>}-Platzhalter. Wenn du also nur eine Anzahl von Werten oder Texten an einen Befehl weitergeben musst, brauchst du für diesen einfachen Fall kein Skript zu schreiben.

Das Skript

Mit einem benutzerdefinierten Skript kannst du die Benutzeroberfläche weiter anpassen, die an den Prozess übergebenen Werte überprüfen und ändern und die Ausgabe verarbeiten, die vom ausgeführten Prozess zurückgesendet wird.

Das Skript selbst sollte nur Funktionen erstellen und zuweisen, wenn es ausgeführt wird, und nichts ausführen oder ausgeben. Schauen wir uns das folgende Beispielskript an:

Beispielskript für eine einfache skriptgesteuerte Benutzeroberfläche
 1function checkForm() {
 2    var ok = true;
 3    if (actions.ui.field1.text.length == 0) {
 4        ok = false;
 5    }
 6    if (actions.ui.field2.text.length == 0) {
 7        ok = false;
 8    }
 9    if (actions.ui.field3.plainText.length == 0) {
10        ok = false;
11    }
12    actions.executeButton.enabled = ok;
13}
14
15actions.onInit = function() {
16    actions.ui.field1.textChanged.connect(checkForm);
17    actions.ui.field2.textChanged.connect(checkForm);
18    actions.ui.field3.textChanged.connect(checkForm);
19    actions.executeButton.text = "Start";
20    actions.executeButton.enabled = false;
21}
22
23actions.onExecute = function() {
24    actions.writeLine("Wert von field1 = " + actions.uivalue.field1);
25    actions.uivalue.field2 = "x_" + actions.uivalue.field2;
26    actions.startProcess();
27}
28
29actions.onFinished = function(returnCode) {
30    actions.closeDialog();
31}
32
33actions.onProcessOutput = function(line) {
34    actions.writeLineWarning( line );
35}

Das Skript deklariert und weist lediglich Funktionen zu, die vom Client zum richtigen Zeitpunkt ausgeführt werden. Die Hauptschnittstelle bildet dabei das globale Objekt actions welches deinem Skript zur Verfügung steht.

Überblick über die actions Schnittstelle

Das folgende UML-Diagramm zeigt die Schnittstelle des globalen actions Objekts:

../../_images/script-interface.jpg

Die Schnittstelle für das globale actions Objekt.

Eigenschaften

Eigenschaft

Beschreibung

ui

Dieses Objekt repräsentiert dein individuelles Benutzeroberflächen-Widget. Hier kannst du auf die einzelnen Elemente deiner Benutzeroberfläche zugreifen.

uivalue

Die Map mit allen Werten der Benutzeroberfläche. Füge neue Werte in diese Map ein, um sie mit dem ui-Platzhalter verfügbar zu machen.

executeButton

Der Button, um den Befehl auszuführen. Nutze diesen, um den Button zu aktivieren oder zu deaktivieren und um den Text auf dem Button zu ändern.

Callbacks

Die Callbacks können mit eigenen Funktionen überschrieben werden. Alle Callbacks sind optional. Wenn du ihnen keine Funktion zuweist, gibt es ein Standardverhalten, wie im Abschnitt Wie es funktioniert, Schritt für Schritt beschrieben.

Callback

Beschreibung

onInit

Dieser Callback wird aufgerufen, kurz nachdem die Schnittstelle erstellt wurde, aber bevor die Benutzeroberfläche angezeigt wird. Nutze diesen Callback, um deine Benutzeroberfläche zu initialisieren und alles für die Präsentation vorzubereiten.

onExecute

Dieser Callback wird aufgerufen, wenn der Benutzer auf den Ausführungsbutton klickt. Konvertiere und überprüfe deine Werte und rufe startProcess() auf.

onFinished

Dieser Callback wird aufgerufen, nachdem der Prozess abgeschlossen ist. Du kannst dem Benutzer ein Feedback geben oder einfach das Fenster schließen.

onProcessOutput

Für jede Zeile der Prozessausgabe vom gestarteten Programm wird dieser Callback aufgerufen. Nutze ihn, um die Ausgabe zu analysieren oder dem Benutzer Feedback zu geben.

Funktionen

Die Funktionen in der folgenden Tabelle sind dafür gedacht, von deinen Callbacks aus aufgerufen zu werden. Du darfst keine davon außerhalb eines Callbacks aufrufen.

Funktion

Beschreibung

startProcess()

Um den Prozess zu starten.

closeDialog()

Um das Dialogfenster der Benutzeroberfläche zu schließen.

writeLine(text)

Um eine Zeile in der Konsole zu schreiben.

writeLineWarning(text)

Um eine orangefarbene Warnung in der Konsole zu schreiben.

writeLineError(text)

Um eine rote Fehlerzeile in der Konsole zu schreiben.

writeLineDebug(text)

Um eine graue Zeile in der Konsole zu schreiben.

Das actions.ui Objekt

Das globale ui Objekt ist ein QWidget, das deine individuelle Benutzeroberfläche repräsentiert, die du mit der Benutzeroberflächendeklarationsdatei bereitgestellt hast. Du kannst diese Benutzeroberfläche anpassen oder Verbindungen zu den Signalen der Benutzeroberflächenelemente herstellen, um Werte zu verifizieren, wie im folgenden Beispiel gezeigt:

Beispiel, wie Signale zur Überprüfung eines Formulars verwendet werden
 1function checkForm() {
 2    var ok = true;
 3    if (actions.ui.field1.text.length == 0) {
 4        ok = false;
 5    }
 6    if (actions.ui.field2.text.length == 0) {
 7        ok = false;
 8    }
 9    if (actions.ui.field3.plainText.length == 0) {
10        ok = false;
11    }
12    actions.executeButton.enabled = ok;
13}
14
15actions.onInit = function() {
16    actions.ui.field1.textChanged.connect(checkForm);
17    actions.ui.field2.textChanged.connect(checkForm);
18    actions.ui.field3.textChanged.connect(checkForm);
19}

Für Details über die verfügbaren Eigenschaften und Methoden der Benutzeroberflächenelemente, siehe die Qt Dokumentation. Die meisten von den verschiedenen Widgets bereitgestellten Eigenschaften können in einem Skript gelesen und modifiziert werden.

Die actions.uivalue Map

Die actions.uivalue Map des Aktionsobjekts wird mit allen automatisch gesammelten Werten aus der Benutzeroberfläche gefüllt. Dies geschieht direkt nachdem der Benutzer den Ausführen-Button drückt und bevor die onExecute Funktion aufgerufen wird.

Du kannst nicht nur die Map lesen, sondern auch eigene Werte hinzufügen oder die vorhandenen Werte in dieser Map ändern, wie im folgenden Beispiel gezeigt:

1actions.onExecute = function() {
2    actions.writeLine("Wert von field1 = " + actions.uivalue.field1);
3    actions.uivalue.field2 = "x_" + actions.uivalue.field2;
4    actions.startProcess();
5}

Die Namen der Werte sind die eindeutigen Namen der Benutzeroberflächenelemente. Wenn du startProcess() aufrufst, werden die Werte von uivalue zu diesem Zeitpunkt verwendet, um die {ui:...} Platzhalter im Programm und den Argumentwerten der Aktion zu ersetzen.

Die actions.executeButton Eigenschaft

Die executeButton Eigenschaft ist ein QPushButton, der den im Dialogfenster angezeigten Ausführen-Button repräsentiert. Du kannst diese Eigenschaft verwenden, um auf diesen Button zuzugreifen und den Zustand oder Text des Buttons zu ändern. Das folgende Beispiel deaktiviert den Button zu Beginn und ändert den Text auf dem Button zu Start.

1actions.onInit = function() {
2    actions.executeButton.text = "Start";
3    actions.executeButton.enabled = false;
4}

Der onInit Callback

Dieser Callback wird einmal aufgerufen, direkt nachdem die Benutzeroberfläche erstellt wurde. Nutze diesen Callback, um die Benutzeroberfläche zu initialisieren, den Ausführungsbutton zu ändern und dich mit den Signalen deiner Benutzeroberfläche zu verbinden.

 1function checkForm() {
 2    var ok = true;
 3    if (actions.ui.field1.text.length == 0) {
 4        ok = false;
 5    }
 6    if (actions.ui.field2.text.length == 0) {
 7        ok = false;
 8    }
 9    if (actions.ui.field3.plainText.length == 0) {
10        ok = false;
11    }
12    actions.executeButton.enabled = ok;
13}
14
15actions.onInit = function() {
16    actions.ui.field1.textChanged.connect(checkForm);
17    actions.ui.field2.textChanged.connect(checkForm);
18    actions.ui.field3.textChanged.connect(checkForm);
19    actions.executeButton.text = "Start";
20    actions.executeButton.enabled = false;
21}

Der onExecute Callback

Dieser Callback wird aufgerufen, direkt nachdem der Benutzer auf den Ausführungsbutton geklickt hat. Bevor dieser Callback aufgerufen wird, werden alle Werte für die uivalue Map gesammelt. Nutze diesen Callback, um die Ausführung vorzubereiten, zu ändern oder benutzerdefinierte Werte für den {ui:...} Platzhalter hinzuzufügen.

Du musst in jedem Fall startProcess() am Ende dieses Callbacks aufrufen.

Hinweis

Beachte, dass du den Startprozess in diesem Stadium nicht abbrechen kannst. Um die Ausführung zu verhindern, deaktiviere den Ausführungsbutton.

1actions.onExecute = function() {
2    actions.writeLine("Wert von field1 = " + actions.uivalue.field1);
3    actions.uivalue.field2 = "x_" + actions.uivalue.field2;
4    actions.startProcess();
5}

Der onFinished(code) Callback

Dieser Callback wird aufgerufen, nachdem der Prozess beendet wurde. Er erfordert einen Parameter, der den Exit-Code des aufgerufenen Prozesses übernimmt. Du kannst ihn nutzen, um spezielles Feedback an den Benutzer vorzubereiten oder eine Fehlermeldung anzuzeigen.

Du kannst closeWindow() am Ende dieses Callbacks aufrufen, um das Fenster zu schließen. Wenn du diese Methode nicht aufrufst, bleibt der Dialog offen und du kannst ihn für eigene Zwecke nutzen. Die Dialogschaltflächen werden automatisch durch einen einzigen Close Button ersetzt, den du vom Skript aus nicht steuern kannst.

1actions.onFinished = function(returnCode) {
2    actions.closeDialog();
3}

Der onProcessOutput(line) Callback

Dieser Callback wird für jede Ausgabezeile des laufenden Prozesses aufgerufen. Um die Ausgabe auf der Konsole anzuzeigen, musst du diese Zeile an eine der writeLine Funktionen weitergeben.

Nutze diese Funktion, wenn du die Ausgabe verarbeiten musst oder sie nach Daten durchsuchen möchtest, die du dem Benutzer anzeigen möchtest.

1actions.onProcessOutput = function(line) {
2    actions.writeLine( line );
3}

Die startProcess() Funktion

Rufe diese Methode am Ende des onExecute Callbacks auf, um den Prozess zu starten. Du darfst diese Methode nur einmal aufrufen. Du kannst diese Methode früher aufrufen, um den Prozess von einem anderen Ereignis auf der Benutzeroberfläche zu starten.

1actions.onExecute = function() {
2    // ...
3    actions.startProcess();
4}

Die closeDialog() Funktion

Rufe diese Methode am Ende des onFinished Callbacks auf, um den Dialog zu schließen. Du kannst diese Methode früher aufrufen, um den Dialog von einem anderen Ereignis zu schließen.

1actions.onFinished = function(returnCode) {
2    actions.closeDialog();
3}

Die writeLine...(text) Funktionen

Diese vier Methoden werden verwendet, um Text auf der Konsole auszugeben. Die Konsole wird automatisch sichtbar gemacht, wenn du Text darauf schreibst. Die verschiedenen Funktionen schreiben den Text lediglich in verschiedenen Farben auf die Konsole.

1writeLine(text); // Weisser Text
2writeLineWarning(text); // Oranger Text
3writeLineError(text); // Roter Text
4writeLineDebug(text); // Grauer Text