get a property value of an object from its ViewProvider

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

get a property value of an object from its ViewProvider

Post by Zolko »

Hello,

in C++ (not Python !) I would like to retrieve some property of the base oject from its ViewProvider. The idea being that the ViewProvider returns different icons for different values of that property. I know how to do it in Python but I want to try something in C++ (some might already guess where this is going ...)

In the ViewProvider.cpp I tried:

Code: Select all

App::PropertyString* type = this->getObject()->Type.getStrValue();

Code: Select all

App::PropertyString* type = this->getObject().Type.getStrValue();
but apparently this() return an App::DocumentObject which doesn't have "Type" set, although my object does.

Is there a way to query a given property of an object from within its ViewProvider ? Am I missing something ?

Thanx
try the Assembly4 workbench for FreCAD — tutorials here and here
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: get a property value of an object from its ViewProvider

Post by openBrain »

I didn't actually tried but are you sure 'Type' is a public member variable ?
If it's private/protected, you have to access it through a getter (something like 'getType()').
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: get a property value of an object from its ViewProvider

Post by Zolko »

openBrain wrote: Thu Jul 15, 2021 10:45 am I didn't actually tried but are you sure 'Type' is a public member variable ?
In this case, yes. Actually, it's for a Part. My idea is to adapt it's ViewProvider so that it returns the standard icon always except if its Type is set to "Assembly". Before submitting a proposal for this I wanted to try it first.

The Type is defined in ~/src/App/Part.h

Code: Select all

public:
    /// type of the part
    PropertyString Type;
and I would like the ViewProviderPart to test for this property in getIcon():

Code: Select all

QIcon ViewProviderPart::getIcon(void) const
{
    // the Type property of the base Part object
    // App::DocumentObject* part = this->getObject();
    // App::PropertyString* type = this->getObject()->Type.getStrValue();
    
    return mergeGreyableOverlayIcons (Gui::BitmapFactory().pixmap(sPixmap));
}
and return aPixmap (which I have defined in ViewProviderPart.h) if Type=="Assembly" and sPixmap (the standard geofeaturegroup icon) for everything else. But this->getObject() returns an App::DocumentObject and not an App::Part, and thus hasn't the Type property:

Code: Select all

error: ‘class App::DocumentObject’ has no member named ‘Type’
App::PropertyString* type = this->getObject()->Type.getStrValue();

Is there a way to retrieve this "Type" property of Part.h in the ViewProviderPart.cpp ?
try the Assembly4 workbench for FreCAD — tutorials here and here
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: get a property value of an object from its ViewProvider

Post by openBrain »

I see.
As you are in ViewProviderPart, I think it's safe to assume that object is necessarily a Part and then a static cast should be OK.

Code: Select all

App::Part* part = static_cast<App::Part*>(this->getObject());
Then you should be able ti use 'part->Type'
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: get a property value of an object from its ViewProvider

Post by Zolko »

openBrain wrote: Fri Jul 16, 2021 1:13 pm As you are in ViewProviderPart, I think it's safe to assume that object is necessarily a Part and then a static cast should be OK.

Code: Select all

App::Part* part = static_cast<App::Part*>(this->getObject());
great, yes, that worked.

Then you should be able ti use 'part->Type'
but I didn't succeed in "using" Type". When I do:

Code: Select all

App::PropertyString* type = part->Type;

I get the error:

Code: Select all

error: cannot convert ‘App::PropertyString’ to ‘App::PropertyString*’ in initialization
App::PropertyString* type = part->Type;

Ideally, what I'd like to do is (in pseudo-code):

Code: Select all

const char* pixmap = sPixmap;                   // this works
App::PropertyString* type = part->Type;         // this doesn't work
if (type == "Assembly") { pixmap = aPixmap }
return mergeGreyableOverlayIcons (Gui::BitmapFactory().pixmap(pixmap));   // this works

Any idea what I could try for that ?


EDIT: std::string type = part->Type.getStrValue(); did the trick
Last edited by Zolko on Sat Jul 17, 2021 5:37 pm, edited 1 time in total.
try the Assembly4 workbench for FreCAD — tutorials here and here
User avatar
adrianinsaval
Veteran
Posts: 5551
Joined: Thu Apr 05, 2018 5:15 pm

Re: get a property value of an object from its ViewProvider

Post by adrianinsaval »

it's probably

Code: Select all

part->Type.getStrValue();
User avatar
Zolko
Veteran
Posts: 2213
Joined: Mon Dec 17, 2018 10:02 am

Re: get a property value of an object from its ViewProvider

Post by Zolko »

adrianinsaval wrote: Sat Jul 17, 2021 5:25 pm it's probably

Code: Select all

part->Type.getStrValue();
Ha, yes, that did it !

Geoassembly.png
Geoassembly.png (152.67 KiB) Viewed 1400 times

I will propose this in the UI/UIX forum
try the Assembly4 workbench for FreCAD — tutorials here and here
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: get a property value of an object from its ViewProvider

Post by openBrain »

Zolko wrote: Sat Jul 17, 2021 5:06 pm but I didn't succeed in "using" Type". When I do:

Code: Select all

App::PropertyString* type = part->Type;
I get the error:

Code: Select all

error: cannot convert ‘App::PropertyString’ to ‘App::PropertyString*’ in initialization
App::PropertyString* type = part->Type;
For sake of completeness on this point, if you look at the 'Type' declaration, it is a (direct) variable and not a pointer.
So if you want to use it, you have to do :

Code: Select all

App::PropertyString type = part->Type;
And if for some reason you really need a pointer :

Code: Select all

App::PropertyString* type = &part->Type;
Post Reply