Interaktivní skriptové akce
Úvod
Sekce “Úvod”Skriptové akce jsou skripty, které přidávají položku do nabídky a/nebo panelu nástrojů a které mohou zpracovávat interakce s uživatelem. Skriptové akce zůstávají aktivní, dokud je uživatel neukončí nebo dokud se samy neukončí.
Události
Sekce “Události”Jakmile je skriptová akce spuštěna, zpracovává různé události, dokud není ukončena. Událost je něco, co nastane, pokud se něco děje. Například pokud je skriptová akce spuštěna, je zavolána beginEvent. Pokud uživatel klikne na entitu, spustí se událost pickEntity, pokud uživatel klikne na souřadnici, nastane událost pickCoordinate atd.
Minimální struktura skriptové akce je následující:
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ázkový skript přidá nabídku do dolní části nabídky Různé > Příklady. Text nabídky je “Minimal Example”.
Všimněte si, že aby byl skript nalezen, musí název souboru odpovídat názvu třídy, tj. v tomto případě “ExMyMinimal.js”. Musí se také nacházet v adresáři se stejným názvem “ExMyMinimal”, takže tento skript lze například umístit do scripts/Misc/ExMyMinimal/ExMyMinimal.js.
Své skripty můžete také umístit do místní složky scripts ve svém domovském adresáři. Chcete-li zjistit přesnou složku, otevřete dialogové okno „O aplikaci“ (Nápověda > O aplikaci QCAD…) a přejděte na kartu Systém. Tam uvidíte umístění dat u položky Data directory. To je adresář, ve kterém musíte vytvořit podsložku s názvem scripts a v ní další podsložky, jednu složku pro každý skriptovací nástroj, například /cesta/k/adresáři dat/scripts/MyScripts/MyScript1/MyScript1.js
Přesné umístění závisí na vašem systému a jeho konfiguraci.
Přidání beginEvent
Sekce “Přidání beginEvent”Výše uvedený skript je plně funkční a lze jej spustit. Při spuštění však ve skutečnosti nic nedělá. Navíc po spuštění zůstává skript aktivní, dokud jej uživatel neukončí kliknutím pravým tlačítkem myši. Abychom to změnili, implementujme beginEvent, aby vypsal něco do historie příkazového řádku QCAD a ukončil akci:
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"]);};Pokud je nyní nástroj Různé > Příklady > Minimal Example spuštěn, vypíše “Hello World!” do historie příkazového řádku (řádek 12) a poté se ukončí (řádek 14).
Pokud skript nevyžaduje žádnou interakci s uživatelem, lze takový skript použít k přidání nabídky, která něco udělá a poté se ukončí. Příklady takových akcí jsou Zobrazit > Automatické přiblížení, Vybrat > Vybrat vše, Upravit > Odstranit atd.
Přidání interakce
Sekce “Přidání interakce”Jakmile skript vyžaduje jakýkoli druh interakce s uživatelem, musíme implementovat více obslužných rutin událostí a sdělit skriptu, co má uživatel udělat dále (např. výběr entity nebo definování souřadnice). V dalším kroku vstoupíme do stavu, ve kterém akce očekává souřadnici od uživatele. Poté nakreslíme kružnici na každé pozici, na kterou uživatel klikne nebo kterou 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 již akci neukončujeme okamžitě, ale necháme ji běžet, dokud ji uživatel neukončí (kliknutí pravým tlačítkem nebo Escape). Poté implementujeme pickCoordinate, abychom uložili pozici kurzoru myši nebo zadanou souřadnici a buď aktualizovali náhled, nebo použili operaci (tj. přidali kružnici). pickCoordinate se zavolá pokaždé, když uživatel pohne myší, aby se zobrazil náhled plánované operace. Když uživatel klikne nebo zadá souřadnici, je zavolána s parametrem preview nastaveným na false, aby indikovala, že byla vybrána nebo zadána definitivní souřadnice.
updatePreview na řádku 22 zobrazuje náhled operace vrácené funkcí getOperation, zatímco applyOperation na řádku 25 skutečně použije operaci na náš dokument.
getOperation musí být implementována tak, aby vrátila operaci k náhledu nebo použití na dokument. To je o něco složitější než to, co jsme viděli v jednoduchém API výše. Je to proto, že jedna operace může být použita k přidání více objektů, úpravě objektů nebo odstranění objektů.
Přidání widgetů do panelu nástrojů s možnostmi
Sekce “Přidání widgetů do panelu nástrojů s možnostmi”Kružnice nakreslená v našem příkladu má vždy poloměr 1 kreslicí jednotky (viz řádek 33). V dalším kroku chceme uživateli umožnit zadat poloměr kružnice. QCAD obvykle používá panel nástrojů s možnostmi v horní části k zobrazení a změně takových parametrů nástroje. K tomu musíme definovat, které widgety chceme zobrazit v panelu nástrojů s možnostmi a jaké parametry ovládají. To lze provést pomocí souboru UI, souboru XML, který definuje widget a jeho obsah. Soubory UI lze pohodlně navrhovat pomocí softwaru zvaného Qt Designer, který je součástí sady nástrojů Qt. Pro tento příklad použijeme jednoduchý soubor UI, který lze také vytvořit v textovém editoru (soubor 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>Soubor UI definuje dva widgety: popisek (QLabel) a řádkové pole pro úpravy (RMathLineEdit). Důležitý je název řádkového pole pro úpravy (“Radius”). Widget je prostřednictvím tohoto názvu automaticky propojen s naším skriptem. Vše, co musíme v našem skriptu udělat, je definovat, který soubor UI chceme použít (řádek 9), a implementovat novou obslužnou rutinu události s názvem slotRadiusChanged, což je “slot” + [název našeho řádkového pole pro úpravy] + “Changed” (řádek 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"]);};Tato nová funkce slotRadiusChanged se zavolá pokaždé, když uživatel zadá nový poloměr. Nastaví členskou proměnnou this.radius, která se následně použije při vytváření kružnice v getOperation.
Všechny skripty v QCAD jsou založeny na jednom z těchto konceptů popsaných v tomto návodu.
Protože každý nástroj v QCAD je na nejvyšší úrovni implementován jako skript, je k dispozici mnoho ukázkových skriptů. Najdete je v našem úložišti git.