Interaktivne skriptne radnje
Skriptne radnje su skripte koje dodaju stavku u izbornik i/ili alatnu traku i koje mogu obrađivati korisničke interakcije. Skriptne radnje ostaju aktivne dok ih korisnik ne prekine ili dok se same ne prekinu.
Događaji
Section titled “Događaji”Čim se skriptna radnja pokrene, obrađuje razne događaje sve dok se ne prekine. Događaj je nešto što se pojavljuje kad se nešto zbiva. Na primjer, ako se skriptna radnja pokrene, poziva se beginEvent. Ako korisnik klikne na entitet, pokreće se događaj pickEntity, ako korisnik klikne na koordinatu, dolazi do događaja pickCoordinate itd.
Minimalna struktura skriptne radnje je sljedeća:
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"]);};Ova primjerna skripta dodaje izbornik na dno izbornika Razno > Primjeri. Tekst izbornika je “Minimal Example”.
Imajte na umu da, kako bi se skripta mogla pronaći, ime datoteke mora odgovarati imenu klase, tj. “ExMyMinimal.js” u ovom slučaju. Također se mora nalaziti unutar direktorija s istim imenom “ExMyMinimal”, pa se ova skripta može, na primjer, staviti u scripts/Misc/ExMyMinimal/ExMyMinimal.js.
Svoje skripte možete staviti i u lokalnu mapu scripts unutar svoje korisničke početne mape. Kako biste saznali točnu mapu, otvorite dijaloški okvir „O programu“ (Pomoć > O programu QCAD…) i prijeđite na karticu Sustav. Ondje možete vidjeti lokaciju podataka pod Data directory. To je direktorij u kojem morate stvoriti podmapu naziva scripts, a u njoj podmape, po jednu mapu za svaki skriptni alat, na primjer /putanja/do/direktorija podataka/scripts/MyScripts/MyScript1/MyScript1.js
Točna lokacija ovisi o vašem sustavu i njegovoj konfiguraciji.
Dodavanje beginEvent
Section titled “Dodavanje beginEvent”Gornja skripta je potpuno funkcionalna i može se pokrenuti. Međutim, kada se pokrene, zapravo ne radi ništa. Štoviše, kad se pokrene, skripta ostaje aktivna dok je korisnik ne prekine klikom na desnu tipku miša. Da bismo to promijenili, implementirajmo beginEvent kako bismo ispisali nešto u povijest naredbenog retka QCAD-a i prekinuli radnju:
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"]);};Ako se alat Razno > Primjeri > Minimal Example sada pokrene, ispisuje “Hello World!” u povijest naredbenog retka (redak 12), a zatim se prekida (redak 14).
Ako skripta ne zahtijeva nikakvu korisničku interakciju, takva se skripta može koristiti za dodavanje izbornika koji nešto obavi, a zatim se prekine. Primjeri takvih radnji su Prikaz > Automatsko zumiranje, Odabir > Odaberi sve, Uređivanje > Izbriši itd.
Dodavanje interakcije
Section titled “Dodavanje interakcije”Čim skripta zahtijeva bilo kakvu korisničku interakciju, moramo implementirati više rukovatelja događajima i reći skripti što korisnik treba učiniti sljedeće (npr. odabrati entitet ili definirati koordinatu). U sljedećem koraku ulazimo u stanje u kojem radnja očekuje koordinatu od korisnika. Zatim crtamo krug na svakom mjestu na koje korisnik klikne ili koje unese.
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"]);};U beginEvent više ne prekidamo radnju odmah, već je puštamo da se izvodi dok je korisnik ne prekine (desni klik ili Escape). Zatim implementiramo pickCoordinate za pohranjivanje položaja pokazivača miša ili unesene koordinate te za ažuriranje pretpregleda ili primjenu operacije (tj. dodavanje kruga). pickCoordinate se poziva kad god korisnik pomakne miša za prikaz pretpregleda planirane operacije. Kada korisnik klikne ili unese koordinatu, poziva se s parametrom preview postavljenim na false kako bi se naznačilo da je definitivna koordinata odabrana ili unesena.
updatePreview u retku 22 pretpregledava operaciju koju vraća getOperation, dok applyOperation u retku 25 zapravo primjenjuje operaciju na naš dokument.
getOperation mora biti implementiran tako da vraća operaciju za pretpregled ili primjenu na dokument. To je nešto složenije od onoga što smo vidjeli u jednostavnom API-ju gore. To je zato što se jedna operacija može koristiti za dodavanje više objekata, izmjenu objekata ili brisanje objekata.
Dodavanje widgeta u alatnu traku s opcijama
Section titled “Dodavanje widgeta u alatnu traku s opcijama”Krug nacrtan u našem primjeru uvijek ima polumjer od 1 jedinice crteža (pogledajte redak 33). U sljedećem koraku želimo korisniku omogućiti unos polumjera za krug. QCAD obično koristi alatnu traku s opcijama na vrhu za prikaz i promjenu takvih parametara alata. Za to moramo definirati koje widgete želimo prikazati u alatnoj traci s opcijama i koje parametre oni kontroliraju. To se može učiniti pomoću UI datoteke, XML datoteke koja definira widget i njegov sadržaj. UI datoteke mogu se udobno dizajnirati pomoću softvera Qt Designer koji dolazi kao dio Qt kompleta alata. Za ovaj primjer koristimo jednostavnu UI datoteku koja se može stvoriti i u uređivaču teksta (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>UI datoteka definira dva widgeta: oznaku (QLabel) i polje za unos (RMathLineEdit). Važno je ime polja za unos (“Radius”). Widget se putem ovog imena automatski povezuje s našom skriptom. Sve što moramo učiniti u našoj skripti jest definirati koju UI datoteku želimo koristiti (redak 9) i implementirati novi rukovatelj događajem pod nazivom slotRadiusChanged, to jest “slot” + [ime našeg polja za unos] + “Changed” (redak 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"]);};Ova nova funkcija slotRadiusChanged poziva se kad god korisnik unese novi polumjer. Postavlja člansku varijablu this.radius koja se potom koristi pri stvaranju kruga u getOperation.
Sve skripte u QCAD-u temelje se na jednom od ovih koncepata opisanih u ovom vodiču.
Budući da je svaki alat u QCAD-u na najvišoj razini implementiran kao skripta, dostupno je mnoštvo primjernih skripti. Možete ih pronaći u našem git repozitoriju.