Interaktivna skriptna dejanja
Skriptna dejanja so skripti, ki dodajo vnos v meni in/ali orodno vrstico in ki lahko obravnavajo uporabniške interakcije. Skriptna dejanja ostanejo aktivna, dokler jih uporabnik ne prekine ali dokler se sama ne prekinejo.
Dogodki
Section titled “Dogodki”Takoj ko se skriptno dejanje zažene, obravnava različne dogodke, dokler ni prekinjeno. Dogodek je nekaj, kar se zgodi, če se nekaj dogaja. Na primer, če se skriptno dejanje zažene, se pokliče beginEvent. Če uporabnik klikne entiteto, se sproži dogodek pickEntity, če uporabnik klikne koordinato, se pojavi dogodek pickCoordinate itd.
Minimalna struktura skriptnega dejanja je naslednja:
include("scripts/EAction.js");
function ExMyMinimal(guiAction) { EAction.call(this, guiAction);}
ExMyMinimal.prototype = new EAction();
ExMyMinimal.init = function(basePath) { var action = new RGuiAction(qsTr("&Minimal Example"), RMainWindowQt.getMainWindow()); action.setRequiresDocument(true); action.setScriptFile(basePath + "/ExMyMinimal.js"); action.setGroupSortOrder(100000); action.setSortOrder(0); action.setWidgetNames(["ExamplesMenu"]);};Ta primer skripta doda meni na dno menija Razno > Primeri. Besedilo menija je “Minimal Example”.
Upoštevajte, da se mora za to, da se skript najde, ime datoteke ujemati z imenom razreda, tj. v tem primeru “ExMyMinimal.js”. Nahajati se mora tudi v imeniku z enakim imenom “ExMyMinimal”, tako da je ta skript mogoče na primer postaviti v scripts/Misc/ExMyMinimal/ExMyMinimal.js.
Svoje skripte lahko shranite tudi v lokalno mapo scripts znotraj svoje domače uporabniške mape. Če želite izvedeti točno mapo, odprite pogovorno okno »O programu« (Pomoč > O programu QCAD…) in pojdite na zavihek Sistem. Tam lahko vidite lokacijo podatkov pod Data directory. To je imenik, v katerem morate ustvariti podmapo z imenom scripts, v njej pa podmape, po eno mapo za vsako skriptno orodje, na primer /pot/do/podatkovnega imenika/scripts/MyScripts/MyScript1/MyScript1.js
Točna lokacija je odvisna od vašega sistema in njegove konfiguracije.
Dodajanje beginEvent
Section titled “Dodajanje beginEvent”Zgornji skript je popolnoma funkcionalen in ga je mogoče sprožiti. Vendar pa ob sprožitvi dejansko ne naredi ničesar. Poleg tega, ko je enkrat sprožen, skript ostane aktiven, dokler ga uporabnik ne prekine s klikom desnega gumba miške. Da to spremenimo, implementirajmo beginEvent, da izpiše nekaj v zgodovino ukazne vrstice QCAD in prekine dejanje:
include("scripts/EAction.js");
function ExMyMinimal(guiAction) { EAction.call(this, guiAction);}
ExMyMinimal.prototype = new EAction();
ExMyMinimal.prototype.beginEvent = function() { EAction.prototype.beginEvent.call(this);
EAction.handleUserMessage("Hello World!");
this.terminate();};
ExMyMinimal.init = function(basePath) { var action = new RGuiAction(qsTr("&Minimal Example"), RMainWindowQt.getMainWindow()); action.setRequiresDocument(true); action.setScriptFile(basePath + "/ExMyMinimal.js"); action.setGroupSortOrder(100000); action.setSortOrder(0); action.setWidgetNames(["ExamplesMenu"]);};Če se orodje Razno > Primeri > Minimal Example zdaj zažene, izpiše “Hello World!” v zgodovino ukazne vrstice (vrstica 12) in se nato prekine (vrstica 14).
Če skript ne zahteva nobene uporabniške interakcije, je tak skript mogoče uporabiti za dodajanje menija, ki nekaj naredi in se nato prekine. Primeri takih dejanj so Pogled > Samodejni zoom, Izberi > Izberi vse, Uredi > Izbriši itd.
Dodajanje interakcije
Section titled “Dodajanje interakcije”Takoj ko skript zahteva kakršno koli uporabniško interakcijo, moramo implementirati več upravljavcev dogodkov in skriptu povedati, kaj mora uporabnik narediti naslednje (npr. izbrati entiteto ali definirati koordinato). V naslednjem koraku vstopimo v stanje, v katerem dejanje pričakuje koordinato od uporabnika. Nato narišemo krog na vsakem položaju, ki ga uporabnik klikne ali vnese.
include("scripts/EAction.js");
function ExMyMinimal(guiAction) { EAction.call(this, guiAction);
this.pos = undefined;}
ExMyMinimal.prototype = new EAction();
ExMyMinimal.prototype.beginEvent = function() { EAction.prototype.beginEvent.call(this);
var di = this.getDocumentInterface(); di.setClickMode(RAction.PickCoordinate);};
ExMyMinimal.prototype.pickCoordinate = function(event, preview) { this.pos = event.getModelPosition();
if (preview) { this.updatePreview(); } else { this.applyOperation(); }};
ExMyMinimal.prototype.getOperation = function(preview) { var doc = this.getDocument();
var op = new RAddObjectOperation(); var circle = new RCircle(this.pos, 1); op.addObject(shapeToEntity(doc, circle)); return op;};
ExMyMinimal.init = function(basePath) { var action = new RGuiAction(qsTr("&Minimal Example"), RMainWindowQt.getMainWindow()); action.setRequiresDocument(true); action.setScriptFile(basePath + "/ExMyMinimal.js"); action.setGroupSortOrder(100000); action.setSortOrder(0); action.setWidgetNames(["ExamplesMenu"]);};V beginEvent dejanja ne prekinemo več takoj, ampak ga pustimo teči, dokler ga uporabnik ne prekine (desni klik ali Escape). Nato implementiramo pickCoordinate, da shranimo položaj miškinega kazalca ali vneseno koordinato in bodisi posodobimo predogled bodisi uporabimo operacijo (tj. dodamo krog). pickCoordinate se pokliče vsakič, ko uporabnik premakne miško, da se prikaže predogled načrtovane operacije. Ko uporabnik klikne ali vnese koordinato, se pokliče s parametrom preview, nastavljenim na false, da nakaže, da je bila izbrana ali vnesena dokončna koordinata.
updatePreview v vrstici 22 predogleda operacijo, ki jo vrne getOperation, medtem ko applyOperation v vrstici 25 dejansko uporabi operacijo na našem dokumentu.
getOperation mora biti implementirana tako, da vrne operacijo za predogled ali uporabo na dokumentu. To je nekoliko bolj zapleteno od tega, kar smo videli v preprostem API zgoraj. To je zato, ker je mogoče eno samo operacijo uporabiti za dodajanje več objektov, spreminjanje objektov ali brisanje objektov.
Dodajanje gradnikov v orodno vrstico z možnostmi
Section titled “Dodajanje gradnikov v orodno vrstico z možnostmi”Krog, narisan v našem primeru, ima vedno polmer 1 risalne enote (glejte vrstico 33). V naslednjem koraku želimo uporabniku omogočiti vnos polmera za krog. QCAD običajno uporablja orodno vrstico z možnostmi na vrhu za prikaz in spreminjanje takih parametrov orodja. Za to moramo definirati, katere gradnike želimo prikazati v orodni vrstici z možnostmi in katere parametre nadzorujejo. To je mogoče narediti z datoteko UI, datoteko XML, ki definira gradnik in njegovo vsebino. Datoteke UI je mogoče udobno oblikovati z uporabo programske opreme, imenovane Qt Designer, ki je del zbirke orodij Qt. Za ta primer uporabljamo preprosto datoteko UI, ki jo je mogoče ustvariti tudi v urejevalniku besedila (datoteka ExMyMinimal.ui):
<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"> <class>ExMyMinimal</class> <widget class="QWidget" name="ExMyMinimal"> <layout class="QHBoxLayout"> <item> <widget class="QLabel" name="RadiusLabel"> <property name="text"> <string>&Radius:</string> </property> <property name="buddy"> <cstring>Radius</cstring> </property> </widget> </item> <item> <widget class="RMathLineEdit" name="Radius"> <property name="text"> <string notr="true">1</string> </property> </widget> </item> </layout> </widget> <customwidgets> <customwidget> <class>RMathLineEdit</class> <extends>QLineEdit</extends> <header>RMathLineEdit.h</header> </customwidget> </customwidgets> <resources/> <connections/></ui>Datoteka UI definira dva gradnika: oznako (QLabel) in urejevalnik vrstice (RMathLineEdit). Pomembno je ime urejevalnika vrstice (“Radius”). Gradnik se prek tega imena samodejno poveže z našim skriptom. V našem skriptu moramo storiti le to, da definiramo, katero datoteko UI želimo uporabiti (vrstica 9), in implementiramo nov upravljavec dogodkov, imenovan slotRadiusChanged, to je “slot” + [ime našega urejevalnika vrstice] + “Changed” (vrstica 45):
include("scripts/EAction.js");
function ExMyMinimal(guiAction) { EAction.call(this, guiAction);
this.pos = undefined; this.radius = undefined;
this.setUiOptions("ExMyMinimal.ui");}
ExMyMinimal.prototype = new EAction();
ExMyMinimal.prototype.beginEvent = function() { EAction.prototype.beginEvent.call(this);
var di = this.getDocumentInterface(); di.setClickMode(RAction.PickCoordinate);};
ExMyMinimal.prototype.pickCoordinate = function(event, preview) { this.pos = event.getModelPosition();
if (preview) { this.updatePreview(); } else { this.applyOperation(); }};
ExMyMinimal.prototype.getOperation = function(preview) { if (isNull(this.pos) || isNull(this.radius)) { return undefined; }
var doc = this.getDocument();
var op = new RAddObjectOperation(); var circle = new RCircle(this.pos, this.radius); op.addObject(shapeToEntity(doc, circle)); return op;};
ExMyMinimal.prototype.slotRadiusChanged = function(v) { this.radius = v; this.updatePreview();};
ExMyMinimal.init = function(basePath) { var action = new RGuiAction(qsTr("&Minimal Example"), RMainWindowQt.getMainWindow()); action.setRequiresDocument(true); action.setScriptFile(basePath + "/ExMyMinimal.js"); action.setGroupSortOrder(100000); action.setSortOrder(0); action.setWidgetNames(["ExamplesMenu"]);};Ta nova funkcija slotRadiusChanged se pokliče vsakič, ko uporabnik vnese nov polmer. Nastavi člansko spremenljivko this.radius, ki se nato uporabi pri ustvarjanju kroga v getOperation.
Vsi skripti v QCAD temeljijo na enem od teh konceptov, opisanih v tej vadnici.
Ker je vsako orodje v QCAD na najvišji ravni implementirano kot skript, je na voljo veliko primerov skriptov. Najdete jih v našem repozitoriju git.