Gå til indhold

Oprette et QCAD-plugin

QCAD-plugins kan bruges til at udvide QCAD med funktionalitet implementeret i C eller C++.

Alle QCAD-plugins skal være direkte eller indirekte afledt af QObject og den abstrakte basisklasse RPluginInterface.

For vores første, minimalistiske eksempel-plugin tilføjer vi tomme eller minimalistiske implementeringer for de fleste metoder af RPluginInterface direkte til header-filen. Denne indledende struktur af header-filen kan kopieres for at få et første fungerende plugin, der kan indlæses i QCAD.

#include <QObject>
#include <QScriptEngine>
#include "RPluginInterface.h"
class RExamplePlugin : public QObject, public RPluginInterface
{
Q_OBJECT
Q_INTERFACES(RPluginInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "org.qcad.exampleplugin")
#endif
public:
virtual bool init() { return true; }
virtual void uninit(bool) {}
virtual void postInit(InitStatus status) {}
virtual void initScriptExtensions(QScriptEngine& engine) {}
virtual RPluginInfo getPluginInfo();
virtual bool checkLicense() { return true; }
};

For metoden getPluginInfo tilføjer vi en simpel implementering til cpp-filen for at kunne se noget i QCAD’s om-dialog.

#include "RExamplePlugin.h"
RPluginInfo RExamplePlugin::getPluginInfo() {
RPluginInfo ret;
ret.set("Version", "1.0");
ret.set("ID", "EXAMPLE");
ret.set("Name", "Example Plugin");
ret.set("License", "GPLv3");
ret.set("URL", "http://qcad.org");
return ret;
}
#if QT_VERSION < 0x050000
QT_BEGIN_NAMESPACE
Q_EXPORT_PLUGIN2(example, RExamplePlugin)
QT_END_NAMESPACE
#endif

For at kompilere vores plugin har vi også brug for en Qt-projektfil, der kan omdannes til en Makefile med Qt qmake.

CONFIG += plugin
TARGET = example
include(../../../shared.pri)
TEMPLATE = lib
HEADERS = RExamplePlugin.h
SOURCES = RExamplePlugin.cpp
DESTDIR = ../../../plugins
LIBS += -lqcadcore -lqcadgui -lqcadecmaapi

Include på linje 3 bør pege på filen shared.pri i installationen af QCAD-kildekoden (f.eks. qcad/shared.pri). Som DESTDIR ønsker du måske at vælge plugins-mappen i en fungerende QCAD-installation, så pluginet kompileres det rigtige sted, hvorfra det også kan indlæses af QCAD.

Dit plugin kan kompileres med disse tre filer, hvilket opretter filen qcad/plugins/qcadexample.dll eller libqcadexample.so eller libqcadexample.dylib.

Bemærk: Hvis du kører en QCAD-binær fil kompileret i debug-tilstand, skal pluginet også kompileres i debug-tilstand. Hvis du kører QCAD i release-tilstand, skal pluginet også kompileres i release-tilstand.

For at kompilere pluginet i debug-tilstand skal du køre:

Linux / macOS:

qmake
make debug

Windows:

qmake
nmake debug

For at kompilere i release-tilstand skal du i stedet køre make release eller nmake release.

Pluginet vil naturligvis endnu ikke gøre noget nyttigt, men du bør kunne se dit plugin i QCAD’s om-dialog:

Eksempel-pluginet vist i QCAD's om-dialog

Hvis du ikke kan se dit plugin, så tjek for fejl i terminalen, mens du starter QCAD. Du ser muligvis også en fejlmeddelelse i om-dialogen.

Kompilere scripts som ressourcer ind i et plugin

Sektion kaldt “Kompilere scripts som ressourcer ind i et plugin”

QCAD-plugins kan bruges til at kompilere en samling af scripts og andre ressourcer (ui-filer, ikoner osv.) ind i et plugin. Dette har den fordel, at koden fra flere ECMAScript-filer kan samles inde i en enkelt, kompileret binær fil. Plugins har en tendens til at indlæses hurtigere end individuelle filer fra disk og fylder mindre diskplads.

Lad os antage, at der er en mappe scripts/MyTool med en fil MyTool.js, som indeholder et QCAD-værktøj, implementeret i ECMAScript. Værktøjet tilføjer sig selv øverst i Diverse-menuen og udskriver “Hello World”, når det udløses.

include("scripts/EAction.js");
function MyTool(guiAction) {
EAction.call(this, guiAction);
}
MyTool.prototype = new EAction();
MyTool.prototype.beginEvent = function() {
EAction.prototype.beginEvent.call(this);
EAction.handleUserMessage("Hello World");
this.terminate();
};
MyTool.init = function(basePath) {
var action = new RGuiAction("&MyTool", RMainWindowQt.getMainWindow());
action.setRequiresDocument(true);
action.setScriptFile(basePath + "/MyTool.js");
action.setGroupSortOrder(0);
action.setSortOrder(0);
action.setWidgetNames(["MiscMenu"]);
};

For at kompilere dette script-værktøj ind i vores C++-plugin skal vi oprette en Qt-ressourcefil, der peger qmake mod den fil, vi vil kompilere ind i pluginet:

<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file alias="scripts/MyTool/MyTool.js">scripts/MyTool/MyTool.js</file>
</qresource>
</RCC>

qrc-filen angiver de stier, hvorunder ressourcer skal gøres tilgængelige i Qt’s ressourcesystem (alias=“scripts/MyTool/MyTool.js”), og den faktiske sti, hvor filen kan findes på disken (bruges kun til kompilering). Ovenstående eksempel betyder, at der er en fil på disken under scripts/MyTool/MyTool.js, som vil blive kompileret ind i pluginet. Så snart pluginet er indlæst, vil filen være tilgængelig under stien “:/scripts/MyTool/MyTool.js”. QCAD finder værktøjet automatisk under den sti, da det scanner mappen “scripts” såvel som “:/scripts” for scripts.

Vi skal også tilføje qrc-filen til projektfilen (exampleplugin.pro) ved at tilføje følgende linje:

RESOURCES = scripts.qrc

Efter redigering af filen exampleplugin.pro skal du køre qmake og make igen og indlæse pluginet. Der bør nu være en menupost “MyTool” øverst i Diverse-menuen i QCAD.

Du kan finde den komplette kildekode for dette eksempel-plugin på:

https://github.com/qcad/qcad/tree/master/support/examples/exampleplugin

  • Hvis dit plugin kompileres, men ikke kan indlæses af QCAD, så sørg for, at den samme Qt-version bruges som til QCAD (se Hjælp > Om QCAD). Sørg for, at hvis QCAD køres i release-tilstand, er dit plugin også kompileret i release-tilstand.
  • Start QCAD fra en terminal eller kommandolinjen, og tjek konsoloutputtet for fejlmeddelelser. Udskriv meddelelser i dit plugin for at bekræfte, at det indlæses. For eksempel i din init-funktion.
  • Tjek om-dialogen (Hjælp > Om QCAD > Plugins) for fejlmeddelelser.