Scripting question

Discussion forum for C++ and script developers who are using the QCAD development platform or who are looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files, scripts and screenshots.

Post one question per topic.

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Scripting question

Post by socool » Sun Jun 17, 2012 12:57 pm

Hello I'm new in QCad scripting. I use QCad 3.0.0 RC5 Trial for Linux. I have two questions.

1) How can I add something to current DWG or DXF file by my script. I use:

Code: Select all

// init application name:
qApp.applicationName = "Nacti body";

// init DWG / DXF exporter:
RDwgExporterFactory.registerFileExporter();

var storage = new RMemoryStorage();
var spatialIndex = new RSpatialIndexNavel();
var document = new RDocument(storage, spatialIndex);
document.setUnit(RS.Meter);

// create document interface (needed for file export functionality):
var di = new RDocumentInterface(document);

// create an operation:
var operation = new RAddObjectsOperation();

...

 // apply operation to document:
 operation.apply(document);

// export document to DWG, version 2000:
di.exportFile(file_name.dwg "DWG 2000");
It create new file file_name.dwg with results of my script, but I need to add results of my script to existing file f.e. current_file.dwg

2) I'm not able to open GUI with created DWG file at the end of my script. I must open QCad GUI and load file manually. I run my script by command:

Code: Select all

./qcad-trial -autostart my_script.js
I know that is non-gui command but

Code: Select all

./qcad -exec my_script.js
don't work to me, probably because I use only trial version. But it doesn't matter, because I want use boolean variable which define if file should be open or not.

I try use something like this:

Code: Select all

var open = true;
if (open){
include("scripts/File/OpenFile/OpenFile.js");
var action = new OpenFile();
action.openFile("my_file.dwg");
action.finishEvent();
}
But i take error mesage:

Code: Select all

NewFile.prototype.beginEvent [1339929706108] 
EAction.prototype.showUiOptions: no options tool bar 
Creating storage... 
Creating spatial index... 
Creating document... 
RDocument::setCurrentBlock: removing block:  22 
Init idle and default actions... 
EAction.prototype.showUiOptions: no options tool bar 
./qcad-trial: řádek 36:  6058 Neoprávněný přístup do paměti (SIGSEGV)                     LD_LIBRARY_PATH="$DIR" "$binary" $OPT1 $OPT2 "$@"

User avatar
andrew
Site Admin
Posts: 9019
Joined: Fri Mar 30, 2007 6:07 am

Re: Scripting quetion

Post by andrew » Mon Jun 18, 2012 10:55 am

Have a look at one of the example scripts, for example:
scripts/Examples/DrawExamples/ExDrawBoundingBox/ExDrawBoundingBox.js

It shows how you can create a script that adds itself to the GUI (e.g. as menu entry) and operates on the currently loaded drawing.

You can then use such a script interactively:
- start QCAD
- load a drawing
- choose the appropriate menu to start the script

Or from the command line:
./qcad mydrawing.dxf -exec scripts/path/to/myscript.js

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting quetion

Post by socool » Mon Jun 25, 2012 12:05 pm

Thanks for your help.

Pleas can you tell me what is wrong in this simple script:

Code: Select all

var document = this.getDocument();
var di = this.getDocumentInterface();

  var poloha = new RVector(10, 20);    
  var operation2 = new RAddObjectsOperation();
  operation2.addObject(new RCircleEntity(document, new RCircleData(poloha, 5)));
    
di.applyOperation(operatin2);
It should draw circle in current document.

I try run this script from command line by command:

Code: Select all

./qcad-trial file_name.dwg -exec file_name.js
But I take this error mesage:

Code: Select all

Warning:  QScriptEngine::newVariant(): changing class of non-QScriptObject not supported
Warning:  QScriptEngine::newVariant(): changing class of non-QScriptObject not supported
Warning:  RScriptHandlerEcma::eval: script engine exception:  "TypeError: Result of expression 'this.getDocument' [undefined] is not a function." 
Warning:  "<anonymous>()@/home/socool/data/programovani/qcad-nacti_body/nacti_body-stavajici.js:3" 
Warning:  At least one uncaught exception: 
Warning:  "<anonymous>()@/home/socool/data/programovani/qcad-nacti_body/nacti_body-stavajici.js:3"

User avatar
andrew
Site Admin
Posts: 9019
Joined: Fri Mar 30, 2007 6:07 am

Re: Scripting quetion

Post by andrew » Mon Jun 25, 2012 12:44 pm

QCAD scripting does not work like that. A script has to be an 'action', derived from RAction. In your script there is no 'this' context since you are not in the context of a class at all.

Again, I strongly suggest to have a look at the example script indicated above. Take this as a starting point and start modifying from there.

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting quetion

Post by socool » Mon Jun 25, 2012 7:02 pm

I start with script to draw a spiral. ExMathSpiral. I can change the body of function to draw something else, but I'm not able to change function name, script file name and directory with script. Probably there is some dependences to other files in directory MathExamples but I don't know which one. There is only MathExamples.js included at begin of the script but when I move the script file to other directory and change the path to MathExamples.js the script stop working.

User avatar
andrew
Site Admin
Posts: 9019
Joined: Fri Mar 30, 2007 6:07 am

Re: Scripting quetion

Post by andrew » Tue Jun 26, 2012 5:53 pm

There are requirements on script directories, script files and class names (basically they all have to be the same).

This tutorial documents the procedure to create a new tool in detail, step by step:

http://www.ribbonsoft.com/doc/qcad/3.0/ ... _tool.html

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting quetion

Post by socool » Sat Jun 30, 2012 2:29 pm

Thanks for the link. The tutorial was very useful for me.

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting quetion

Post by socool » Sat Jun 30, 2012 8:38 pm

In the tutorial "Command Line Tools > Creating a Drawing" start with new document. How can I start with current .dwg file with some drawing and continue drawing to this file by command line script (no-gui mode). I can create Tool by tutorial "Creating a New Tool" which can do that, but it can't run it in no-gui mode.

User avatar
andrew
Site Admin
Posts: 9019
Joined: Fri Mar 30, 2007 6:07 am

Re: Scripting quetion

Post by andrew » Sun Jul 01, 2012 2:36 pm

What you are looking for is likely the method RDocumentInterface::importFile:

Code: Select all

// register DXF / DWG importers:
RDwgImporter.registerFileImporter();
...
var di = new RDocumentInterface(document);
...
if (di.importFile("mydrawing.dxf") != RDocumentInterface.IoErrorNoError) {
    qWarning("Cannot import file");
    // abort...
    return;
}

// continue working with the document...

Have also a look at the command line tools included with QCAD to get an idea of how to create and use command line (no-gui) tools with QCAD 3.

For example dwg2bmp, implemented in scripts/Tools/Dwg2Bmp/Dwg2Bmp.js:

You can start it with:
./qcad -no-gui -autostart scripts/Tools/Dwg2Bmp/Dwg2Bmp.js

Or use the Bash script included for convenience:
dwg2bmp.sh


Related tutorials:
http://www.ribbonsoft.com/doc/qcad/3.0/ ... tools.html

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting quetion

Post by socool » Sun Jul 01, 2012 4:27 pm

Thanks for your help Andrew. This is what I was looking for.

I have one more question to Persistent Widgets in tutorial. There are only two buttons in one Button Box. "OK" Store the new user input, "Cancel" terminate function. How can I set action to other buttons in my GUI. I want to create third button for this action:

Code: Select all

var file = QFileDialog.getOpenFileName(null, qsTr("Open file"), QDir.homePath(), qsTr("Text Files (*.txt);;All Files (*)"));

User avatar
andrew
Site Admin
Posts: 9019
Joined: Fri Mar 30, 2007 6:07 am

Re: Scripting quetion

Post by andrew » Sun Jul 01, 2012 6:22 pm

GUI programming in QCAD is all standard Qt programming, except that it's ECMAScript and not C++. The classes, methods and the concepts are exactly the same:
http://doc.qt.nokia.com/4.7/

For a button, you could for example create a QToolButton:
http://doc.qt.nokia.com/4.7/qtoolbutton.html

Or a QPushButton:
http://doc.qt.nokia.com/4.7/qpushbutton.html

For both of them the signal "clicked" is emitted when the button is clicked:
http://doc.qt.nokia.com/4.7/qabstractbu ... ml#clicked

In ECMAScript, that can look for example like this:

Code: Select all

var button = new QToolButton(dialog);
button.clicked.connect(function() { // do something });
To create dialogs, layouts, etc, you may prefer to use the Qt Designer UI design WYSIWYG tool. The resulting .ui files can be used directly in your ECMAScript classes like the file PersistentWidgets.ui is used by the PersistentWidgets example.

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting quetion

Post by socool » Sun Jul 01, 2012 7:12 pm

Thanks for help with button.

Now I'm not sure if is clear create layer by script in current document provided I don't know that layer with this name didn't be created in this document yet. Or it's better fist check, by some condition, that layer don't exist. Something like:

Code: Select all

if (RLayer.getName() != "MyLayer"){
  var operation1 = new RAddObjectsOperation();
  var linetypeId = document.getLinetypeId("continuous");
  var mylayer = new RLayer(document, "MyLayer", false, false, new RColor("black"), linetypeId, RLineweight.Weight025);
  operation1.addObject(mylayer);
};

document.setCurrentLayer("MyLayer");
If this way is more clear, how to define condition corectly?

User avatar
andrew
Site Admin
Posts: 9019
Joined: Fri Mar 30, 2007 6:07 am

Re: Scripting question

Post by andrew » Tue Jul 03, 2012 9:47 pm

You can check if a layer exists with:

Code: Select all

if (document.hasLayer("mylayer")) { ... }

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting question

Post by socool » Thu Jul 05, 2012 3:48 pm

Thanks for all your help Andrew.

socool
Junior Member
Posts: 13
Joined: Sun Jun 17, 2012 12:16 pm

Re: Scripting question

Post by socool » Mon Jul 16, 2012 6:39 pm

Hello,

can you help me with correct syntax for write text to file. I know how to read text from file line by line, I use it to read coordinates:

Code: Select all

var file

file = new QFile(file_name);
var file_info = new QFileInfo(file);
   if (!file_info.exists()) { throw new Error("File " + file_name + " not exist"); }
   
file.open(QIODevice.OpenMode(QIODevice.ReadOnly, QIODevice.Text));
  var input = new QTextStream(soubor);

while (!input.atEnd()) {   
  var line = input.readLine();
};
I want to write new line with coordinates to file. I found some examples for QT:

Code: Select all

QFile file("result.txt");
file.open(QIODevice::WriteRead | QIODevice::Text);
QDataStream out(&file);
out << QString("victory");
The first two lines should be similar like to file read:

Code: Select all

file = new QFile(file_name);
file.open(QIODevice.OpenMode(QIODevice.WriteRead, QIODevice.Text));
But I don't know correct syntax for QCad for next two lines. Also I want to add line to create text file,if it not exist yet.

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”