[Solved]Listing Entity's Properties
Moderator: andrew
Forum rules
Always indicate your operating system and QCAD version.
Attach drawing files, scripts and screenshots.
Post one question per topic.
Always indicate your operating system and QCAD version.
Attach drawing files, scripts and screenshots.
Post one question per topic.
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
[Solved]Listing Entity's Properties
Windows 7, Qcad 3.12.4
Greetings.
I am a fair noob in JavaScript, but wanted to make a plugin for QCad. I have been poking about in Qt Designer so I'm fairly sure I can make a reasonable UI for it, but having explored the code of Property Editor, I have failed to fully grasp how to even understand how to read the property values of entities. I also don't quite grasp all the properties available and how to use them to get data.
In short, I wanted to make a plugin that acted like the widget plugins (those that appear on the right side of the screen, Property Editor, Layer List, Block List, etc) that read the properties of every entity on the drawing board and listed them on a listview, organized according to their printing order on, for example, a laser printer. (I may be wrong, but i think this order is defined by the 'Handle' variable)
Here's an example:
3 entities on the drawing board. A Line (0;0 to 10;10), an arc (10;10 to 20;10 with 15;10 as center), and a line (20;10 to 20;20). Entities should not need to be selected.
The listview should show:
Line Xi Yi Xf Yf Cx Cy
1 0 0 10 10 - -
2 10 10 20 10 15 10
3 20 10 20 20 - -
This should be enough for me to grasp how this works and point me towards where I want to evolve the plugin.
Thanks in advance.
Greetings.
I am a fair noob in JavaScript, but wanted to make a plugin for QCad. I have been poking about in Qt Designer so I'm fairly sure I can make a reasonable UI for it, but having explored the code of Property Editor, I have failed to fully grasp how to even understand how to read the property values of entities. I also don't quite grasp all the properties available and how to use them to get data.
In short, I wanted to make a plugin that acted like the widget plugins (those that appear on the right side of the screen, Property Editor, Layer List, Block List, etc) that read the properties of every entity on the drawing board and listed them on a listview, organized according to their printing order on, for example, a laser printer. (I may be wrong, but i think this order is defined by the 'Handle' variable)
Here's an example:
3 entities on the drawing board. A Line (0;0 to 10;10), an arc (10;10 to 20;10 with 15;10 as center), and a line (20;10 to 20;20). Entities should not need to be selected.
The listview should show:
Line Xi Yi Xf Yf Cx Cy
1 0 0 10 10 - -
2 10 10 20 10 15 10
3 20 10 20 20 - -
This should be enough for me to grasp how this works and point me towards where I want to evolve the plugin.
Thanks in advance.
Last edited by Ghost_of_Magellan on Fri Apr 15, 2016 7:06 pm, edited 1 time in total.
Re: Listing Entity's Properties
I'd start by implementing a text display widget with a button to manually update its contents. You can always later trigger the update automatically whenever something changes in the drawing (this will of course slow down the drawing process for larger drawings).
To iterate over all visible entities in the document and list some of their properties:
To iterate over all visible entities in the document and list some of their properties:
var doc = EAction.getDocument(); var entityIds = doc.queryAllVisibleEntities(); // order entities back to front: entityIds = doc.getStorage().orderBackToFront(entityIds); for (var i = 0; i < entityIds.length; ++i) { var entity = doc.queryEntity(entityIds); var line = "" + entity.getId() + " "; if (isLineEntity(entity)) { line += entity.getStartPoint().x + " "; line += entity.getStartPoint().y + " "; line += entity.getEndPoint().x + " "; line += entity.getEndPoint().y; } // handle other entity types... // add string in 'line' to widget... }
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Greetings, and thank you for the example, andrew.
I will attempt to make it work later in the day and will report on my progress as soon as I do.
Thank you once again.
I will attempt to make it work later in the day and will report on my progress as soon as I do.
Thank you once again.
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Greetings. I apologize for the delay in responding, I was away for most of the week and weekend.
I have successfully tested your example, though I printed the results only in command line, and I have a few questions.
This is the code so far:
Not much differing from the given code.
So here begin my questions. Imagine that we make a drawing with two entities, two lines with coordinates: 0;0 to 10;0 and 10;0 to 20;10. The script will print:
So far so good, everything perfect. Then I copy ythose two entities and paste them twice over, so I have a drawing with 6 entities. The script will print the following:
The Id atributed to each entity is correct, there is no problem there. However, when I save the dxf file and put into my printing program, it prints exactly in the listing order of the command lines, meaning that it will print Id 53, then 58 (when i wanted it to print 54) and then 56 (when it should print 55), and so on.
I have thought to create a sorting function that would create a temporary copy of entityIds and reorganize it before overwriting entityIds with it, unfortunately, I understand that it will serve of nothing because entityIds is not what actually controls this process but only a variable that holds the data for my observation. I'm assuming the original data, relevant to this issue is in doc.queryAllVisibleEntities();, or any such functions that likely include the doc. class.
Is there any way I can control the printing order through this list so as to allow me to copy and paste segments of the same drawing IN ORDER? I can't find anything like it in the Qcad library functions, though i will admit most of them go a bit over my head.
Thank you once again.
I have successfully tested your example, though I printed the results only in command line, and I have a few questions.
This is the code so far:
Code: Select all
var doc = EAction.getDocument();
var entityIds = doc.queryAllVisibleEntities();
entityIds = doc.getStorage().orderBackToFront(entityIds);
for (var i = 0; i < entityIds.length; ++i) {
var entity = doc.queryEntity(entityIds[i]);
var line = "" + entity.getId() + " ";
if (isLineEntity(entity)) {
line += entity.getStartPoint().x + " ";
line += entity.getStartPoint().y + " ";
line += entity.getEndPoint().x + " ";
line += entity.getEndPoint().y;
}
if (isArcEntity(entity)) {
line += entity.getStartPoint().x + " ";
line += entity.getStartPoint().y + " ";
line += entity.getEndPoint().x + " ";
line += entity.getEndPoint().y + " ";
line += entity.getRadius();
}
appWin.handleUserMessage(line);
}
appWin.handleUserMessage("********** End **********");
So here begin my questions. Imagine that we make a drawing with two entities, two lines with coordinates: 0;0 to 10;0 and 10;0 to 20;10. The script will print:
Code: Select all
53 0 0 10 0
54 10 0 20 10
********** End **********
Code: Select all
53 0 0 10 0
58 50 0 60 10
56 30 0 40 10
54 10 0 20 10
55 20 0 30 0
57 40 0 50 0
********** End **********
I have thought to create a sorting function that would create a temporary copy of entityIds and reorganize it before overwriting entityIds with it, unfortunately, I understand that it will serve of nothing because entityIds is not what actually controls this process but only a variable that holds the data for my observation. I'm assuming the original data, relevant to this issue is in doc.queryAllVisibleEntities();, or any such functions that likely include the doc. class.
Is there any way I can control the printing order through this list so as to allow me to copy and paste segments of the same drawing IN ORDER? I can't find anything like it in the Qcad library functions, though i will admit most of them go a bit over my head.
Thank you once again.
Re: Listing Entity's Properties
The property that controls display order is called 'draw order':
http://www.qcad.org/bugtracker/index.ph ... sk_id=1404
This will be fixed in the next release. For now, you can simply assign another draw order to that entity using the property editor.
You might want to print the draw order in your list for debugging:
entity.getDrawOrder()
Copy / paste should preserve draw order, although I just noticed, there's a bug with the very first entity that is drawn or loaded:http://www.qcad.org/bugtracker/index.ph ... sk_id=1404
This will be fixed in the next release. For now, you can simply assign another draw order to that entity using the property editor.
You might want to print the draw order in your list for debugging:
entity.getDrawOrder()
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Thank you andrew, for the help and the swift reply.
I'll work on it and request additional assistance if necessary.
Should this be my last post until then, then a happy Easter for you and your family.
Juat for the sake of information, this is what the console prints out when I add the printing order as the second column:
I'll work on it and request additional assistance if necessary.
Should this be my last post until then, then a happy Easter for you and your family.
Juat for the sake of information, this is what the console prints out when I add the printing order as the second column:
Code: Select all
ID DrawOrder xi yi xf yf
53 0 0 0 10 0
60 1 50 0 60 10
58 1 30 0 40 10
54 1 10 0 20 10
57 3 20 0 30 0
59 4 40 0 50 0
********** End **********
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Given that this is still on the same matter of printing to a listview, I'll keep it on the same post.
I have been trying to find examples on how to build arrays to put in the data on the entities list and then pass the desired properties onto a listview I have created on Qt designer, but I have been unsuccessful so far in applying it to QCad scripting.
I would apreciate if an example could be provided on how to do it.
To clarify. I have:
that holds the entire data of the whole document and then I have:
that holds the data on a single entity.
What I want is to add the properties of
To a list.
I am assuming to achieve this I first have to prepare the listview or list widget (haven't yet figured out what's the diference between the two) to receive specific data types in a specific number by line, but this too, I'm not sure how to do it.
And then there is the proper way to add the data to the object. I have named the listview "Obj_listview " and the ListWidget "Obj_ListWidget".
My apologies for the basic questions, and thank you.
I have been trying to find examples on how to build arrays to put in the data on the entities list and then pass the desired properties onto a listview I have created on Qt designer, but I have been unsuccessful so far in applying it to QCad scripting.
I would apreciate if an example could be provided on how to do it.
To clarify. I have:
Code: Select all
var entityIds = doc.queryAllVisibleEntities();
entityIds = doc.getStorage().orderBackToFront(entityIds);
Code: Select all
var entity = doc.queryEntity(entityIds[i]);
What I want is to add the properties of
Code: Select all
entity.getStartPoint().x;
entity.getStartPoint().y;
entity.getEndPoint().x;
entity.getEndPoint().y;
I am assuming to achieve this I first have to prepare the listview or list widget (haven't yet figured out what's the diference between the two) to receive specific data types in a specific number by line, but this too, I'm not sure how to do it.
And then there is the proper way to add the data to the object. I have named the listview "Obj_listview " and the ListWidget "Obj_ListWidget".
My apologies for the basic questions, and thank you.
Re: Listing Entity's Properties
If you have a list widget (type QListWidget), you don't need a list view (QListView).
QListWidget is generally easier to handle since it hides the model behind the view from you.
To add an item to a QListWidget, create the QListWidgetItem first:
Then use addItem to add the item to the QListWidget:
http://doc.qt.io/qt-4.8/classes.html
QListWidget is generally easier to handle since it hides the model behind the view from you.
To add an item to a QListWidget, create the QListWidgetItem first:
var item = new QListWidgetItem("some text");Where "some text" is the string to be displayed, for example "x: " + entity.getStartPoint().x + ", y: " + entity.getStartPoint().y...
Then use addItem to add the item to the QListWidget:
myListWidget.addItem(item);Note that this is all Qt API, not QCAD specific. You can find the complete Qt class reference documentation at:
http://doc.qt.io/qt-4.8/classes.html
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Thank you for the reply andrew.
I am assuming then that the list widget and listview only allow one column. Meaning that I cannot define the different pieces of data through diferent columns. Is this correct?
If this is correct, would you recomend using multiple lists to simulate this in a more orderly fashion or do you know of a better method?
Another question, if possible.
In the example you have given me previously, where I use
to retrieve the entire data table and then
to retrieve the line array for the entity in question.
Is it possible for me to, in code and after reordering the var entityIds to my needs, to replace the original data in (Wherever the hell that is)
with my own reordered entityIds?
In the meantime, I have tested the code and failed. What am I doing wrong?
This is my for cycle:
When the script runs it prints the "line" string on the command line, but it does does nothing below that. In this case, not even the appWin.handleUserMessage("Refresh Successful"); appears.
Thank you very much.
I am assuming then that the list widget and listview only allow one column. Meaning that I cannot define the different pieces of data through diferent columns. Is this correct?
If this is correct, would you recomend using multiple lists to simulate this in a more orderly fashion or do you know of a better method?
Another question, if possible.
In the example you have given me previously, where I use
Code: Select all
var entityIds = doc.queryAllVisibleEntities();
Code: Select all
var entity = doc.queryEntity(entityIds[i]);
Is it possible for me to, in code and after reordering the var entityIds to my needs, to replace the original data in
Code: Select all
doc.queryAllVisibleEntities();
with my own reordered entityIds?
In the meantime, I have tested the code and failed. What am I doing wrong?
This is my for cycle:
var doc = EAction.getDocument(); var entityIds = doc.queryAllVisibleEntities(); entityIds = doc.getStorage().orderBackToFront(entityIds); for (var i = 0; i < entityIds.length; ++i) { var entity = doc.queryEntity(entityIds); var line = "" + entity.getId() + " "; line += entity.getDrawOrder() + " "; if (isLineEntity(entity)) { line += entity.getStartPoint().x + " "; line += entity.getStartPoint().y + " "; line += entity.getEndPoint().x + " "; line += entity.getEndPoint().y; } if (isArcEntity(entity)) { line += entity.getStartPoint().x + " "; line += entity.getStartPoint().y + " "; line += entity.getEndPoint().x + " "; line += entity.getEndPoint().y + " "; line += entity.getRadius(); } appWin.handleUserMessage(line); var item = new QListWidgetItem(line); Obj_listWidget.addItem(item); } appWin.handleUserMessage("Refresh Successful");
When the script runs it prints the "line" string on the command line, but it does does nothing below that. In this case, not even the appWin.handleUserMessage("Refresh Successful"); appears.
Thank you very much.
Last edited by Ghost_of_Magellan on Wed Apr 06, 2016 9:44 am, edited 1 time in total.
Re: Listing Entity's Properties
Yes, lists have one column. If you need multiple columns, perhaps QTableWidget if what you are looking for.Ghost_of_Magellan wrote:I am assuming then that the list widget and listview only allow one column. Meaning that I cannot define the different pieces of data through diferent columns.
If I understand your question correctly, you are looking for a way to reorder entities, i.e. change the drawing order of entities, is that correct?Is it possible for me to, in code and after reordering the var entityIds to my needs, to replace the original data in(Wherever the hell that is)Code: Select all
doc.queryAllVisibleEntities();
with my own reordered entityIds?
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
That is correct. Some other option that does not require me to change the order on properties editor by hand. I can think of several ways to reorganize the array, but do not know how to send that order into the core data.If I understand your question correctly, you are looking for a way to reorder entities, i.e. change the drawing order of entities, is that correct?
I have edited my previous post, since I didnt manage to make your example on the adding to the list a success. (You were too fast in replying =D)
Thank you for the advice and I do believe I will follow the suggestion of the table widget.
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Code: Select all
var item = new QListWidgetItem(line);
widgets["Obj_listWidget"].addItem(item);
Thank you andrew.
Re: Listing Entity's Properties
Hint: You might want to start QCAD with the -enable-script-debugger switch to enable the script debugger. The script debugger then pops up whenever there is an error in your script or whenever it reaches a statement. You can then step through your code, investigate variables, etc.
The disadvantage of the script debugger is that there can be unexpected behavior or even crashes due to events being processed in different order, so only use this for debugging.
You can change entities (for example change drawing order) using operations:
Code: Select all
debugger;
The disadvantage of the script debugger is that there can be unexpected behavior or even crashes due to events being processed in different order, so only use this for debugging.
You can change entities (for example change drawing order) using operations:
var op = new RModifyObjectsOperation(); // iterate through entities: for (...) { // query entity from storage (this gives you a clone of the original entity): var entity = ...; // modify clone of entity: entity.setDrawOrder(7); // add entity to operation: op.addObject(entity, false); } // apply operation, this triggers a transaction which records the change for undo, redo: di.applyOperation(op);
-
- Full Member
- Posts: 58
- Joined: Wed Mar 16, 2016 5:10 pm
Re: Listing Entity's Properties
Thank you for the swift reply, as always, andrew.
I do believe I have enough to keep me going for awhile. Eventually, I'll call back with another ridiculous questions, hopefully on another subject and, therefore, on another topic.
Thank you.
I do believe I have enough to keep me going for awhile. Eventually, I'll call back with another ridiculous questions, hopefully on another subject and, therefore, on another topic.
Thank you.