Interaktiiviset skriptitoiminnot
Johdanto
Section titled “Johdanto”Skriptitoiminnot ovat skriptejä, jotka lisäävät kohdan valikkoon ja/tai työkaluriville ja jotka voivat käsitellä käyttäjän vuorovaikutusta. Skriptitoiminnot pysyvät aktiivisina, kunnes käyttäjä lopettaa ne tai kunnes ne lopettavat itsensä.
Tapahtumat
Section titled “Tapahtumat”Heti kun skriptitoiminto käynnistetään, se käsittelee erilaisia tapahtumia, kunnes se lopetetaan. Tapahtuma on jokin asia, joka ilmenee, kun jotain tapahtuu. Esimerkiksi jos skriptitoiminto käynnistetään, kutsutaan beginEvent-tapahtumaa. Jos käyttäjä napsauttaa objektia, laukeaa pickEntity-tapahtuma, jos käyttäjä napsauttaa koordinaattia, tapahtuu pickCoordinate-tapahtuma jne.
Skriptitoiminnon minimaalinen rakenne on seuraava:
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"]);};Tämä esimerkkiskripti lisää valikon valikon Sekalaiset > Esimerkit alaosaan. Valikon teksti on “Minimal Example”.
Huomaa, että jotta skripti löytyisi, tiedostonimen on vastattava luokan nimeä, eli tässä tapauksessa “ExMyMinimal.js”. Sen on myös sijaittava samannimisen hakemiston “ExMyMinimal” sisällä, joten tämä skripti voidaan esimerkiksi sijoittaa polkuun scripts/Misc/ExMyMinimal/ExMyMinimal.js.
Voit myös sijoittaa skriptisi paikalliseen scripts-kansioon kotikansiossasi. Selvittääksesi tarkan kansion avaa tietoja-valintaikkuna (Ohje > Tietoja QCADista…) ja siirry Järjestelmä-välilehdelle. Siellä näet datan sijainnin kohdassa Data directory. Tämän hakemiston alle sinun on luotava alikansio nimeltä scripts ja sen sisään alikansiot, yksi kansio kutakin skriptityökalua kohden, esimerkiksi /polku/datahakemistoon/scripts/MyScripts/MyScript1/MyScript1.js
Tarkka sijainti riippuu järjestelmästäsi ja sen määrityksistä.
beginEvent-tapahtuman lisääminen
Section titled “beginEvent-tapahtuman lisääminen”Yllä oleva skripti on täysin toimiva ja se voidaan käynnistää. Se ei kuitenkaan tosiasiassa tee mitään käynnistettäessä. Lisäksi kerran käynnistettynä skripti pysyy aktiivisena, kunnes käyttäjä lopettaa sen napsauttamalla hiiren oikeaa painiketta. Tämän muuttamiseksi toteutetaan beginEvent tulostamaan jotakin QCADin komentorivihistoriaan ja lopettamaan toiminto:
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"]);};Jos työkalu Sekalaiset > Esimerkit > Minimal Example nyt käynnistetään, se tulostaa “Hello World!” komentorivihistoriaan (rivi 12) ja lopettaa sitten toimintansa (rivi 14).
Jos skripti ei vaadi minkäänlaista käyttäjän vuorovaikutusta, tällaista skriptiä voidaan käyttää lisäämään valikko, joka tekee jotakin ja lopettaa sitten toimintansa. Esimerkkejä tällaisista toiminnoista ovat Näytä > Automaattinen suurennus/zoomaus, Valitse > Valitse kaikki, Muokkaa > Poista jne.
Vuorovaikutuksen lisääminen
Section titled “Vuorovaikutuksen lisääminen”Heti kun skripti vaatii minkäänlaista käyttäjän vuorovaikutusta, meidän on toteutettava lisää tapahtumankäsittelijöitä ja kerrottava skriptille, mitä käyttäjän on tehtävä seuraavaksi (esim. valittava objekti tai määriteltävä koordinaatti). Seuraavassa vaiheessa siirrymme tilaan, jossa toiminto odottaa koordinaattia käyttäjältä. Piirrämme sitten ympyrän jokaiseen kohtaan, jota käyttäjä napsauttaa tai jonka hän syöttää.
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"]);};beginEvent-tapahtumassa emme enää lopeta toimintoa välittömästi, vaan annamme sen jatkua, kunnes käyttäjä lopettaa sen (hiiren oikea napsautus tai Escape). Toteutamme sitten pickCoordinate-tapahtuman tallentamaan hiiren kohdistimen sijainnin tai syötetyn koordinaatin ja joko päivittämään esikatselun tai soveltamaan operaation (eli lisäämään ympyrän). pickCoordinate-tapahtumaa kutsutaan aina, kun käyttäjä liikuttaa hiirtä, jotta suunnitellusta operaatiosta näytetään esikatselu. Kun käyttäjä napsauttaa tai syöttää koordinaatin, sitä kutsutaan parametrilla preview asetettuna arvoon false ilmaisemaan, että lopullinen koordinaatti on valittu tai syötetty.
updatePreview rivillä 22 esikatselee getOperationin palauttaman operaation, kun taas applyOperation rivillä 25 tosiasiassa soveltaa operaation dokumenttiimme.
getOperation on toteutettava palauttamaan operaatio, joka esikatsellaan tai sovelletaan dokumenttiin. Tämä on hieman monimutkaisempaa kuin mitä olemme nähneet yllä olevassa yksinkertaisessa API:ssa. Tämä johtuu siitä, että yhtä operaatiota voidaan käyttää useiden objektien lisäämiseen, objektien muokkaamiseen tai objektien poistamiseen.
Pienoisohjelmien lisääminen asetustyökaluriville
Section titled “Pienoisohjelmien lisääminen asetustyökaluriville”Esimerkissämme piirretyn ympyrän säde on aina 1 piirustusyksikkö (katso rivi 33). Seuraavassa vaiheessa haluamme antaa käyttäjän syöttää säteen ympyrälle. QCAD käyttää yleensä yläreunan asetustyökaluriviä tällaisten työkaluparametrien näyttämiseen ja muuttamiseen. Tätä varten meidän on määriteltävä, mitä pienoisohjelmia haluamme näyttää asetustyökalurivillä ja mitä parametreja ne ohjaavat. Tämä voidaan tehdä UI-tiedostolla, XML-tiedostolla, joka määrittelee pienoisohjelman ja sen sisällön. UI-tiedostot voidaan suunnitella mukavasti Qt Designer -nimisellä ohjelmistolla, joka on osa Qt-työkalupakkia. Tässä esimerkissä käytämme yksinkertaista UI-tiedostoa, joka voidaan luoda myös tekstieditorissa (tiedosto 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-tiedosto määrittelee kaksi pienoisohjelmaa: nimiön (QLabel) ja rivieditorin (RMathLineEdit). Tärkeä on rivieditorin nimi (“Radius”). Pienoisohjelma linkitetään automaattisesti skriptiimme tämän nimen kautta. Skriptissämme meidän tarvitsee vain määritellä, mitä UI-tiedostoa haluamme käyttää (rivi 9), ja toteuttaa uusi tapahtumankäsittelijä nimeltä slotRadiusChanged, eli “slot” + [rivieditorimme nimi] + “Changed” (rivi 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"]);};Tätä uutta funktiota slotRadiusChanged kutsutaan aina, kun käyttäjä syöttää uuden säteen. Se asettaa jäsenmuuttujan this.radius, jota puolestaan käytetään ympyrän luomisessa getOperation-funktiossa.
Kaikki QCADin skriptit perustuvat johonkin näistä tässä oppaassa esitellyistä käsitteistä.
Koska jokainen QCADin työkalu on toteutettu ylätasolla skriptinä, tarjolla on runsaasti esimerkkiskriptejä. Löydät ne git-tietovarastostamme.