QCAD
Open Source 2D CAD
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Menus and Tool Bars

Once you start developing your own script based QCAD tools, you might want to add them to a custom menu or tool bar, so they can be launched in a user friendly and consistent way. These instructions show how menus and tool bars are handled in the ECMAScript structure that comes with QCAD.

If you are not planning to integrate your scripts with the ECMAScripts that come with the QCAD Application, you can of course also use the standard Qt mechanisms (QMenu, QToolBar, QAction) to achieve the same.

Creating the Folder Structure

  1. For your new top level menu, create a new folder inside the scripts folder of your QCAD installation. For this example, we call the folder "MyScripts". The "scripts" folder is located in the QCAD application folder if you are working with Windows or Linux. Under Mac OS X, it's inside the application bundle, under "Contents/Resources/scripts".
  2. Inside the folder "MyScripts", create a new text file called "MyScripts.js". Note that the file name has be to the same as the folder name.
  3. Inside the folder "MyScripts", create another folder for your action (tool). For example "MyAction".
  4. Inside the folder "MyAction", create a new text file called "MyAction.js". Again, the file name has be to the same as the folder name.

The folder structure should now look as shown below:

Implementing the Top Menu

The file "MyScripts.js" defines the base class for all scripts that will be placed in this hierarchy. It also defines the top-level menu title and tool bar name. All actions inside our 'MyScripts' folder are derrived from class 'MyScripts' and use functionality of this base class to define in which menu / tool bar they are shown. For this example, we want the menu to be labeled "My Scripts". Here's the complete code for 'MyScripts.js':

// MyScripts.js
// All actions are derived from class EAction, so we need to
// include this class definition here:
include("../EAction.js");
// Constructor calls base class constructor:
function MyScripts(guiAction) {
EAction.call(this, guiAction);
}
// Derive class MyScripts from class EAction:
MyScripts.prototype = new EAction();
// This static function returns a new or existing QMenu object.
MyScripts.getMenu = function() {
// EAction.getMenu is a helper function that returns an existing
// or new QMenu object with the given title and object name.
// The object name (here "MyScriptMenu") must be unique.
return EAction.getMenu(MyScripts.getTitle(), "MyScriptsMenu");
};
// This static function returns a new or existing QToolBar object.
MyScripts.getToolBar = function() {
// EAction.getToolBar is a helper function that returns an existing
// or new QToolBar object with the given title and object name.
// The object name (here "MyScriptToolBar") must be unique.
return EAction.getToolBar(Edit.getTitle(), "MyScriptToolBar");
};
// This static function defines and returns the title of the menu
// and toolbar.
// The qsTr function marks the title as a translatable string.
MyScripts.getTitle = function() {
return qsTr("My Scripts");
};
// Member function that returns also the title of the menu and toolbar.
// Defined for convenience.
MyScripts.prototype.getTitle = function() {
return MyScripts.getTitle();
};

Creating a New Action

Behind each entry in an application menu and each button in a tool bar, is an action class that implements the behavior of the action. All actions in our example menu structure are derived from the base class MyScripts.

In the folder "MyAction" create a new file called "MyAction.js" with the following contents:

// MyAction.js
// Include base class definition:
include("../MyScripts.js");
// Constructor calls base class constructor:
function MyAction(guiAction) {
MyScripts.call(this, guiAction);
}
// Derive class MyAction from class MyScripts:
MyAction.prototype = new MyScripts();
// This function is called immediately after the constructor when the user
// starts this action. For actions that don't require any user input (for
// example auto zoom), beginEvent does everything and then terminates the
// action.
MyAction.prototype.beginEvent = function() {
// call base class implementation of beginEvent:
MyScripts.prototype.beginEvent.call(this);
// get main application window:
var appWin = EAction.getMainWindow();
// print a message in the console of QCAD:
appWin.handleUserMessage("MyAction() is running...");
// terminate this action immediately:
this.terminate();
};
// MyAction.init() is called by QCAD to initialize the action and create
// the menu / toolbar for it.
MyAction.init = function(basePath) {
// Create a new RGuiAction (extended QAction):
var action = new RGuiAction("&My Action", RMainWindowQt.getMainWindow());
// This action requires a document to be open. If no document is
// open, the menu and tool button are grayed out:
action.setRequiresDocument(true);
// Define the script file that is executed when this action is
// launched:
action.setScriptFile(basePath + "/MyAction.js");
// Set the icon that is shown in the toolbar and on some platforms
// also in the menu:
action.setIcon(basePath + "/MyAction.svg");
// Set the command(s) that can be used on the command line to
// launch this action:
action.setDefaultCommands(["myaction"]);
// Define the sort order of this action. Menus and tool buttons are
// ordered by these values:
action.setGroupSortOrder(80100);
action.setSortOrder(200);
// Set list of widgets this action is added to
// (menus, tool bars, CAD tool bar panels):
action.setWidgetNames(["TutorialsMenu"]);
};

If you start QCAD, you will now see the new top level menu named My Scripts with the entry My Action as well as a new tool bar with one tool button.

menu.png

The action, when started, writes "MyAction() is running..." to the QCAD console and then terminates itself.