Skip to content

Interaktívne skriptové akcie

Skriptové akcie sú skripty, ktoré pridávajú položku do ponuky a/alebo panela nástrojov a ktoré môžu spracúvať interakcie s používateľom. Skriptové akcie zostávajú aktívne, kým ich používateľ neukončí alebo kým sa samy neukončia.

Hneď ako sa skriptová akcia spustí, spracúva rôzne udalosti, kým nie je ukončená. Udalosť je niečo, čo nastane, ak sa niečo deje. Napríklad, ak sa skriptová akcia spustí, zavolá sa beginEvent. Ak používateľ klikne na entitu, spustí sa udalosť pickEntity, ak používateľ klikne na súradnicu, nastane udalosť pickCoordinate atď.

Minimálna štruktúra skriptovej akcie je nasledovná:

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"]);
};

Tento ukážkový skript pridá ponuku do dolnej časti ponuky Rôzne > Príklady. Text ponuky je “Minimal Example”.

Všimnite si, že aby bol skript nájdený, názov súboru sa musí zhodovať s názvom triedy, t. j. v tomto prípade “ExMyMinimal.js”. Musí sa tiež nachádzať v adresári s rovnakým názvom “ExMyMinimal”, takže tento skript možno napríklad umiestniť do scripts/Misc/ExMyMinimal/ExMyMinimal.js.

Svoje skripty môžete umiestniť aj do lokálneho priečinka scripts vo svojom domovskom priečinku. Ak chcete zistiť presný priečinok, otvorte dialógové okno „O programe“ (Pomoc > O programe QCAD…) a prejdite na kartu Systém. Tam uvidíte umiestnenie údajov pri položke Data directory. To je adresár, v ktorom musíte vytvoriť podpriečinok s názvom scripts a v ňom podpriečinky, jeden priečinok pre každý skriptovací nástroj, napríklad /cesta/k/adresáru údajov/scripts/MyScripts/MyScript1/MyScript1.js

Presné umiestnenie závisí od vášho systému a jeho konfigurácie.

Vyššie uvedený skript je plne funkčný a možno ho spustiť. Pri spustení však v skutočnosti nič nerobí. Navyše po spustení zostáva skript aktívny, kým ho používateľ neukončí kliknutím pravým tlačidlom myši. Aby sme to zmenili, implementujme beginEvent, aby vypísal niečo do histórie príkazového riadka QCAD a ukončil akciu:

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"]);
};

Ak sa teraz spustí nástroj Rôzne > Príklady > Minimal Example, vypíše “Hello World!” do histórie príkazového riadka (riadok 12) a potom sa ukončí (riadok 14).

Ak skript nevyžaduje žiadnu interakciu s používateľom, takýto skript možno použiť na pridanie ponuky, ktorá niečo urobí a potom sa ukončí. Príkladmi takýchto akcií sú Zobraziť > Automatické priblíženie, Vybrať > Vybrať všetko, Upraviť > Odstrániť atď.

Hneď ako skript vyžaduje akýkoľvek druh interakcie s používateľom, musíme implementovať viac obslužných rutín udalostí a povedať skriptu, čo má používateľ urobiť ďalej (napr. výber entity alebo definovanie súradnice). V ďalšom kroku vstúpime do stavu, v ktorom akcia očakáva súradnicu od používateľa. Potom nakreslíme kružnicu na každej pozícii, na ktorú používateľ klikne alebo ktorú zadá.

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 už akciu neukončujeme okamžite, ale necháme ju bežať, kým ju používateľ neukončí (kliknutie pravým tlačidlom alebo Escape). Potom implementujeme pickCoordinate, aby sme uložili pozíciu kurzora myši alebo zadanú súradnicu a buď aktualizovali náhľad, alebo použili operáciu (t. j. pridali kružnicu). pickCoordinate sa zavolá zakaždým, keď používateľ pohne myšou, aby sa zobrazil náhľad plánovanej operácie. Keď používateľ klikne alebo zadá súradnicu, zavolá sa s parametrom preview nastaveným na false, aby indikoval, že bola vybratá alebo zadaná definitívna súradnica.

updatePreview na riadku 22 zobrazuje náhľad operácie vrátenej funkciou getOperation, zatiaľ čo applyOperation na riadku 25 skutočne použije operáciu na náš dokument.

getOperation musí byť implementovaná tak, aby vrátila operáciu na náhľad alebo použitie na dokument. Toto je o niečo zložitejšie ako to, čo sme videli v jednoduchom API vyššie. Je to preto, že jedna operácia môže byť použitá na pridanie viacerých objektov, úpravu objektov alebo odstránenie objektov.

Pridanie widgetov do panela nástrojov s možnosťami

Section titled “Pridanie widgetov do panela nástrojov s možnosťami”

Kružnica nakreslená v našom príklade má vždy polomer 1 kresliacej jednotky (pozri riadok 33). V ďalšom kroku chceme používateľovi umožniť zadať polomer kružnice. QCAD zvyčajne používa panel nástrojov s možnosťami v hornej časti na zobrazenie a zmenu takýchto parametrov nástroja. Na to musíme definovať, ktoré widgety chceme zobraziť v paneli nástrojov s možnosťami a aké parametre ovládajú. To možno urobiť pomocou súboru UI, súboru XML, ktorý definuje widget a jeho obsah. Súbory UI možno pohodlne navrhovať pomocou softvéru s názvom Qt Designer, ktorý je súčasťou sady nástrojov Qt. Pre tento príklad používame jednoduchý súbor UI, ktorý možno tiež vytvoriť v textovom editore (súbor 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>&amp;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>

Súbor UI definuje dva widgety: menovku (QLabel) a riadkové pole na úpravy (RMathLineEdit). Dôležitý je názov riadkového poľa na úpravy (“Radius”). Widget je prostredníctvom tohto názvu automaticky prepojený s naším skriptom. Všetko, čo musíme v našom skripte urobiť, je definovať, ktorý súbor UI chceme použiť (riadok 9), a implementovať novú obslužnú rutinu udalosti s názvom slotRadiusChanged, čo je “slot” + [názov nášho riadkového poľa na úpravy] + “Changed” (riadok 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áto nová funkcia slotRadiusChanged sa zavolá zakaždým, keď používateľ zadá nový polomer. Nastaví členskú premennú this.radius, ktorá sa následne použije pri vytváraní kružnice v getOperation.

Všetky skripty v QCAD sú založené na jednom z týchto konceptov opísaných v tomto návode.

Keďže každý nástroj v QCAD je na najvyššej úrovni implementovaný ako skript, je k dispozícii množstvo ukážkových skriptov. Nájdete ich v našom úložisku git.