Skip to content

Tạo một plugin QCAD

Các plugin QCAD có thể được sử dụng để mở rộng QCAD với chức năng được triển khai bằng C hoặc C++.

Tất cả các plugin QCAD phải được dẫn xuất trực tiếp hoặc gián tiếp từ QObject và lớp cơ sở trừu tượng RPluginInterface.

Đối với plugin ví dụ đầu tiên, tối giản của chúng ta, chúng ta thêm các triển khai trống hoặc tối giản cho hầu hết các phương thức của RPluginInterface trực tiếp vào tệp tiêu đề. Cấu trúc ban đầu này của tệp tiêu đề có thể được sao chép để có được một plugin hoạt động đầu tiên có thể được tải vào 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; }
};

Đối với phương thức getPluginInfo, chúng ta thêm một triển khai đơn giản vào tệp cpp để có thể thấy điều gì đó trong hộp thoại giới thiệu của QCAD.

#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

Để biên dịch plugin của chúng ta, chúng ta cũng cần một tệp dự án Qt có thể được chuyển thành Makefile bằng Qt qmake.

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

Include ở dòng 3 nên trỏ đến tệp shared.pri của bản cài đặt mã nguồn QCAD (ví dụ qcad/shared.pri). Là DESTDIR, bạn có thể muốn chọn thư mục plugins của một bản cài đặt QCAD đang hoạt động, để plugin được biên dịch đúng chỗ, nơi mà QCAD cũng có thể tải nó.

Plugin của bạn có thể được biên dịch bằng ba tệp này, tạo ra tệp qcad/plugins/qcadexample.dll hoặc libqcadexample.so hoặc libqcadexample.dylib.

Lưu ý: nếu bạn chạy một tệp nhị phân QCAD được biên dịch ở chế độ gỡ lỗi (debug), plugin cũng phải được biên dịch ở chế độ gỡ lỗi. Nếu bạn chạy QCAD ở chế độ release, plugin cũng phải được biên dịch ở chế độ release.

Để biên dịch plugin ở chế độ gỡ lỗi, hãy chạy:

Linux / macOS:

qmake
make debug

Windows:

qmake
nmake debug

Để biên dịch ở chế độ release, hãy chạy make release hoặc nmake release thay thế.

Rõ ràng, plugin chưa làm gì hữu ích, nhưng bạn sẽ có thể thấy plugin của mình trong hộp thoại giới thiệu của QCAD:

Plugin ví dụ được liệt kê trong hộp thoại giới thiệu của QCAD

Nếu bạn không thể thấy plugin của mình, vui lòng kiểm tra lỗi trong terminal khi khởi động QCAD. Bạn cũng có thể thấy một thông báo lỗi trong hộp thoại giới thiệu.

Biên dịch tập lệnh dưới dạng tài nguyên vào một plugin

Section titled “Biên dịch tập lệnh dưới dạng tài nguyên vào một plugin”

Các plugin QCAD có thể được sử dụng để biên dịch một tập hợp các tập lệnh và các tài nguyên khác (tệp ui, biểu tượng, v.v.) vào một plugin. Điều này có ưu điểm là mã của nhiều tệp ECMAScript có thể được gói bên trong một tệp nhị phân được biên dịch duy nhất. Các plugin có xu hướng tải nhanh hơn các tệp riêng lẻ từ đĩa và chiếm ít dung lượng đĩa hơn.

Giả sử có một thư mục scripts/MyTool với một tệp MyTool.js chứa một công cụ QCAD, được triển khai bằng ECMAScript. Công cụ tự thêm mình vào đầu menu Khác và xuất “Hello World” khi được kích hoạt.

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

Để biên dịch công cụ tập lệnh này vào plugin C++ của chúng ta, chúng ta cần tạo một tệp tài nguyên Qt trỏ qmake đến tệp mà chúng ta muốn biên dịch vào plugin:

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

Tệp qrc liệt kê các đường dẫn mà theo đó các tài nguyên sẽ được cung cấp trong hệ thống tài nguyên của Qt (alias=“scripts/MyTool/MyTool.js”) và đường dẫn thực tế nơi có thể tìm thấy tệp trên đĩa (chỉ dùng để biên dịch). Ví dụ trên nghĩa là có một tệp trên đĩa tại scripts/MyTool/MyTool.js sẽ được biên dịch vào plugin. Ngay khi plugin được tải, tệp sẽ có sẵn tại đường dẫn “:/scripts/MyTool/MyTool.js”. QCAD sẽ tự động tìm thấy công cụ tại đường dẫn đó vì nó quét thư mục “scripts” cũng như “:/scripts” để tìm tập lệnh.

Chúng ta cũng cần thêm tệp qrc vào tệp dự án (exampleplugin.pro) bằng cách thêm dòng sau:

RESOURCES = scripts.qrc

Sau khi chỉnh sửa tệp exampleplugin.pro, hãy chạy lại qmake và make và tải plugin. Bây giờ sẽ có một mục menu “MyTool” ở đầu menu Khác trong QCAD.

Bạn có thể tìm thấy mã nguồn đầy đủ cho plugin ví dụ này tại:

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

  • Nếu plugin của bạn biên dịch được nhưng không thể được QCAD tải, vui lòng đảm bảo rằng cùng một phiên bản Qt được sử dụng như cho QCAD (xem Trợ giúp > Giới thiệu QCAD). Vui lòng đảm bảo rằng nếu QCAD được chạy ở chế độ release, plugin của bạn cũng được biên dịch ở chế độ release.
  • Khởi chạy QCAD từ terminal hoặc dòng lệnh và kiểm tra đầu ra bảng điều khiển để tìm thông báo lỗi. Xuất thông báo trong plugin của bạn để xác nhận rằng nó đang được tải. Ví dụ trong hàm init của bạn.
  • Kiểm tra hộp thoại giới thiệu (Trợ giúp > Giới thiệu QCAD > Plugin) để tìm thông báo lỗi.