Tovább a tartalomhoz

Interaktív szkriptműveletek

A szkriptműveletek olyan szkriptek, amelyek egy bejegyzést adnak hozzá egy menühöz és/vagy eszköztárhoz, és amelyek képesek kezelni a felhasználói interakciókat. A szkriptműveletek aktívak maradnak, amíg a felhasználó le nem zárja őket, vagy amíg maguktól be nem fejeződnek.

Amint a szkriptművelet elindul, különféle eseményeket kezel, amíg le nem zárul. Az esemény olyasmi, ami akkor következik be, ha valami történik. Például ha a szkriptművelet elindul, meghívódik a beginEvent. Ha a felhasználó egy entitásra kattint, egy pickEntity esemény aktiválódik, ha a felhasználó egy koordinátára kattint, egy pickCoordinate esemény következik be stb.

Egy szkriptművelet minimális szerkezete a következő:

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

Ez a példaszkript egy menüt ad hozzá a Egyéb > Példák menü aljához. A menü szövege “Minimal Example”.

Vegye figyelembe, hogy ahhoz, hogy a szkriptet megtalálja, a fájlnévnek meg kell egyeznie az osztálynévvel, azaz ebben az esetben “ExMyMinimal.js”. Ezenkívül egy azonos “ExMyMinimal” nevű könyvtárban kell lennie, így ez a szkript például a scripts/Misc/ExMyMinimal/ExMyMinimal.js helyre tehető.

A szkriptjeit egy helyi scripts mappába is elhelyezheti a saját felhasználói mappájában. A pontos mappa megállapításához nyissa meg a névjegy párbeszédpanelt (Súgó > A QCAD névjegye…), és lépjen a Rendszer fülre. Ott az adatok helyét a Data directory alatt láthatja. Ez az a könyvtár, amely alatt létre kell hoznia egy scripts nevű almappát, abban pedig almappákat, szkripteszközönként egy mappát, például /útvonal/az adatkönyvtárhoz/scripts/MyScripts/MyScript1/MyScript1.js

A pontos hely a rendszertől és annak beállításaitól függ.

A fenti szkript teljesen működőképes és aktiválható. Aktiváláskor azonban valójában nem csinál semmit. Sőt, ha egyszer aktiválták, a szkript aktív marad, amíg a felhasználó a jobb egérgombra kattintva le nem zárja. Ennek megváltoztatásához implementáljuk a beginEvent-et, hogy kiírjon valamit a QCAD parancssori előzményeibe, és lezárja a műveletet:

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

Ha most elindítja a Egyéb > Példák > Minimal Example eszközt, kiírja a “Hello World!” szöveget a parancssori előzményekbe (12. sor), majd befejeződik (14. sor).

Ha egy szkript nem igényel felhasználói interakciót, egy ilyen szkript használható egy olyan menü hozzáadására, amely csinál valamit, majd befejeződik. Ilyen műveletekre példák a Nézet > Automatikus nagyítás, Kijelölés > Összes kijelölése, Szerkesztés > Törlés stb.

Amint egy szkript bármilyen felhasználói interakciót igényel, több eseménykezelőt kell implementálnunk, és meg kell mondanunk a szkriptnek, mit kell tennie a felhasználónak ezután (pl. egy entitás kiválasztása vagy egy koordináta megadása). A következő lépésben belépünk egy olyan állapotba, amelyben a művelet egy koordinátát vár a felhasználótól. Ezután minden pozícióban rajzolunk egy kört, ahová a felhasználó kattint vagy amit megad.

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

A beginEvent-ben már nem fejezzük be azonnal a műveletet, hanem hagyjuk futni, amíg a felhasználó be nem fejezi (jobb kattintás vagy Escape). Ezután implementáljuk a pickCoordinate-ot, hogy tárolja az egérkurzor pozícióját vagy a megadott koordinátát, és vagy frissítse az előnézetet, vagy alkalmazza a műveletet (azaz hozzáadja a kört). A pickCoordinate minden alkalommal meghívódik, amikor a felhasználó mozgatja az egeret, hogy megjelenítse a tervezett művelet előnézetét. Amikor a felhasználó rákattint vagy megad egy koordinátát, a preview paraméter false értékre állítva hívódik meg, jelezve, hogy egy végleges koordinátát választottak ki vagy adtak meg.

A 22. soron lévő updatePreview előnézetet ad a getOperation által visszaadott műveletről, míg a 25. soron lévő applyOperation ténylegesen alkalmazza a műveletet a dokumentumunkra.

A getOperation-t úgy kell implementálni, hogy visszaadja a dokumentumon előnézetezendő vagy alkalmazandó műveletet. Ez valamivel összetettebb, mint amit a fenti egyszerű API-ban láttunk. Ennek oka, hogy egyetlen művelet használható több objektum hozzáadására, objektumok módosítására vagy objektumok törlésére.

Vezérlők hozzáadása a beállítások eszköztárhoz

Szekció neve “Vezérlők hozzáadása a beállítások eszköztárhoz”

A példánkban rajzolt kör sugara mindig 1 rajzegység (lásd a 33. sort). Egy következő lépésben lehetővé szeretnénk tenni a felhasználó számára, hogy megadja a kör sugarát. A QCAD általában a felső beállítások eszköztárat használja az ilyen eszközparaméterek megjelenítésére és módosítására. Ehhez meg kell határoznunk, hogy mely vezérlőket szeretnénk megjeleníteni a beállítások eszköztárban, és milyen paramétereket vezérelnek. Ez megtehető egy UI fájllal, egy XML fájllal, amely meghatároz egy vezérlőt és annak tartalmát. A UI fájlok kényelmesen megtervezhetők egy Qt Designer nevű szoftverrel, amely a Qt eszközkészlet része. Ehhez a példához egy egyszerű UI fájlt használunk, amely szövegszerkesztőben is létrehozható (ExMyMinimal.ui fájl):

<?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>

A UI fájl két vezérlőt határoz meg: egy címkét (QLabel) és egy sorszerkesztőt (RMathLineEdit). Fontos a sorszerkesztő neve (“Radius”). A vezérlő ezen a néven keresztül automatikusan a szkriptünkhöz kapcsolódik. Mindössze annyit kell tennünk a szkriptünkben, hogy meghatározzuk, melyik UI fájlt szeretnénk használni (9. sor), és implementálunk egy slotRadiusChanged nevű új eseménykezelőt, azaz “slot” + [a sorszerkesztőnk neve] + “Changed” (45. sor):

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

Ez az új slotRadiusChanged függvény minden alkalommal meghívódik, amikor a felhasználó új sugarat ad meg. Beállítja a this.radius tagváltozót, amelyet aztán a kör létrehozásakor használ a getOperation.

A QCAD összes szkriptje az ebben az oktatóanyagban vázolt koncepciók egyikén alapul.

Mivel a QCAD minden eszköze a legfelső szinten szkriptként van implementálva, rengeteg példaszkript áll rendelkezésre. Ezeket a git tárolónkban találja.