Computer Assisted Medical Intervention Tool Kit  version 5.2
camitk::Property Class Reference

This class describes a property that can be used in components and actions or any class that needs to be passed to ObjectControler. More...

#include <Property.h>

+ Collaboration diagram for camitk::Property:

Public Member Functions

QVariant getAttribute (QString attName)
 get the current value of a given attribute, see setAttribute() if the attribute attName was never set using setAttribute(), the return QVariant is invalid. More...
 
QStringList getAttributeList ()
 returns the list of attribute names that are specific to this property More...
 
const QString & getDescription () const
 get the description More...
 
QMap< int, QIcon > getEnumIcons () const
 get the enum icons More...
 
QString getEnumTypeName () const
 
QString getEnumValueAsString (const QObject *objectDeclaringTheEnum) const
 Utility method to get the current property value as a string. More...
 
QString getGroupName () const
 get this property subgroup's name More...
 
const QVariant & getInitialValue () const
 return the initial (default) value More...
 
const QString & getName () const
 get the name of the property More...
 
bool getReadOnly () const
 
 Property (QString name, const QVariant &variant, QString description, QString unit)
 Constructor. More...
 
void setAttribute (const QString &attribute, const QVariant &value)
 Set a given property for this attribute. More...
 
void setDescription (QString)
 set the description (can be rich text) More...
 
void setEnumIcons (const QMap< int, QIcon > &enumIcons)
 set the icons for all the enums More...
 
void setEnumTypeName (QString enumTypeName, QObject *objectDeclaringTheEnum)
 if the property's type is an enum, set the name of the registered Qt Enum AND automatically build the enum names that will be used in the GUI. More...
 
void setEnumTypeName (QString)
 if the property's type is an enum, set the name of the registered Qt Enum. More...
 
void setGroupName (QString groupName)
 Set the group name. More...
 
void setReadOnly (bool)
 set this property as read-only More...
 
virtual ~Property ()=default
 Destructor. More...
 

Static Public Member Functions

static PropertygetProperty (QObject *object, QString name)
 get the camitk::Property decoration of a named property of the given QObject or nullptr if object does not have any camitk::Property More...
 

Detailed Description

This class describes a property that can be used in components and actions or any class that needs to be passed to ObjectControler.

A property has a type, a description (to be displayed for example as a tooltip, can be rich-text, see http://qt-project.org/doc/qt-4.8/richtext-html-subset.html for supported html tags), a value, a unit of measurement (SI unit if possible), and some specific attributes (that depends on the type, e.g. minimal and maximal values, single steps, number of decimals, regular expression...). An enum type can also be used for properties.

Properties can be grouped in subgroups, see Property::setGroupName().

Basically this is a way to overcome the Qt Meta Object properties limitations. A camitk::Property enriches a Qt Meta Object property (a very simplified Decorator Design Pattern).

Using camitk::Property instead of directly using Qt Meta Object property helps to build a better interactive GUI (in the property explorer for components and in the ActionWidget for actions). Note that a camitk::Property is represented as a regular Qt Meta Object property as well (the value of the camitk::Property is in fact stored by the Qt Meta Object property)

Here are some examples to get started with:

// Demonstrates how rich text can be used in description
addParameter(new Property("Bool Prop", false, "This a <i>normal</i> bool property.<br/><b>Note:</b> Rich text description!<br/>See also: <a href=\"http://camitk.imag.fr\">CamiTK web page</a>", ""));
// beware: the action takes ownership of the Property pointer
// This means that the line above does not generate memory leak.
// Demonstrates how properties can be set as read-only
// Demonstrates how properties can be grouped.
// Here all read-only properties are assemble in the same eponymic group
Property *readOnlyBool = new Property("Read Only Bool", true, "This a read-only boolean", "");
readOnlyBool->setReadOnly(true);
readOnlyBool->setGroupName("Read Only Properties");
addParameter(readOnlyBool);
// beware: the action takes ownership of the Property pointer
// This means that you should NOT delete readOnlyBool in the action desctructor
// Demonstrates how integer properties can be bounded
Property *boundedInt = new Property("Bounded Int", 12, "An integer bounded between 0 and 20", "");
boundedInt->setAttribute("minimum", 0);
boundedInt->setAttribute("maximum", 20);
boundedInt->setGroupName("Numeric Properties");
addParameter(boundedInt);
// Demonstrates how double properties can be half-bounded
Property *doubleWithMax = new Property("Double With Max", -10.0, "A double with a max value of -4.2", "");
doubleWithMax->setAttribute("maximum", -4.2);
doubleWithMax->setGroupName("Numeric Properties");
addParameter(doubleWithMax);
Property *intWithSingleStep = new Property("Int With Single Step", -10, "An integer with a single step of <i>5</i>", "");
intWithSingleStep->setAttribute("singleStep", 5);
intWithSingleStep->setGroupName("Numeric Properties");
addParameter(intWithSingleStep);
Property *doubleWithStepAndDecimal = new Property("Double With Single Step And Precision", 3.14159, "A double with 5 decimals and a single step of 1.10<sup>-5</sup>", "");
doubleWithStepAndDecimal->setAttribute("singleStep", 10e-6);
doubleWithStepAndDecimal->setAttribute("decimals", 5);
doubleWithStepAndDecimal->setGroupName("Numeric Properties");
addParameter(doubleWithStepAndDecimal);
Property *intWithDecimal = new Property("Int With Precision", 4, "An integer with a precision set to 5 decimals: this should not affect it.", "");
intWithDecimal->setAttribute("decimals", 5);
intWithDecimal->setGroupName("Numeric Properties");
addParameter(intWithDecimal);
Property *readOnlyQVector3D = new Property("Read Only QVector3D", QVector3D(-4.0, 2.0, 0.1), "A read-only QVector3D", "");
readOnlyQVector3D->setReadOnly(true);
readOnlyQVector3D->setGroupName("Read Only Properties");
addParameter(readOnlyQVector3D);
Property *stringWithRegExp = new Property("QString Constrained by RegExp", QString("loweronly"), "A QString contrained to lowercase characters only (no separators, numbers...)", "");
stringWithRegExp->setAttribute("regExp",QRegExp("[a-z]*"));
addParameter(stringWithRegExp);
Property *constrainedQRect = new Property("Constrained QRect", QRect(10,10,20,20), "A QRect contrained to (0,0,50,50)", "");
constrainedQRect->setAttribute("constraint", QRect(0,0,50,50));
addParameter(constrainedQRect);
Property *constrainedQVector3D = new Property("Constrained QVector3D", QVector3D(1.1, 2.2, 3.3), "A constrained QVector3D (not yet implemented)", "");
constrainedQVector3D->setAttribute("constraint", QVector3D(10.0, 10.0, 10.0));
addParameter(constrainedQVector3D);
Property(QString name, const QVariant &variant, QString description, QString unit)
Constructor.
Definition: Property.cpp:33
Note
To create a new Property, prefer using Property. To check if a Property has been added to your Component / Action, use either Component::getProperty() or Action::getProperty() methods. To modify an existing Property's value, check if it exists:
  • if not, create a new instance of Property
  • if yes, directly modify its value by using QObject::setProperty() method.e

The GUI interaction is automatically build and managed by the class ObjectControler.

An example for adding properties to an action can be seen in tutorials/actions/properties. More specifically see the EnumPropertyExample action to learn about how to use enum properties.

The class PropComponent and PropAction in the tutorials demonstrates how to use camitk::Property instead of Qt Meta Object Property.

The available property types are:

Property Type Property Type Id
int QVariant::Int
double QVariant::Double
bool QVariant::Bool
QString QVariant::String
QVector3D QVariant::QVector3D
QColor QVariant::Color
QDate QVariant::Date
QTime QVariant::Time
QChar QVariant::Char
QDateTime QVariant::DateTime
QPoint Variant::Point
QPointF QVariant::PointF
QKeySequence QVariant::KeySequence
QLocale QVariant::Locale
QSize QVariant::Size
QSizeF QVariant::SizeF
QRect QVariant::Rect
QRectF QVariant::RectF
QSizePolicy QVariant::SizePolicy
QFont QVariant::Font
QCursor QVariant::Cursor
enum enumTypeId()
flag flagTypeId()
group groupTypeId()

Possible attributes depends on the property type, mostly (see also QtVariantPropertyManager API doc):

Property Type Attribute Name Attribute Type
int minimum QVariant::Int
int maximum QVariant::Int
int singleStep QVariant::Int
double minimum QVariant::Double
double maximum QVariant::Double
double singleStep QVariant::Double
double decimals QVariant::Int
QString regExp QVariant::RegExp
QDate minimum QVariant::Date
QDate maximum QVariant::Date
QPointF decimals QVariant::Int
QSize minimum QVariant::Size
QSize maximum QVariant::Size
QSizeF minimum QVariant::SizeF
QSizeF maximum QVariant::SizeF
QSizeF decimals QVariant::Int
QRect constraint QVariant::Rect
QRectF constraint QVariant::RectF
QRectF decimals QVariant::Int
enum enumNames QVariant::StringList (note that this can be build automatically)
flag flagNames (NOT IMPLEMENTED YET) QVariant::StringList
Note
For enums, you need to do few things in the C++ class that has a enum typed property:
  • add Q_underscore_OBJECT macro in your class declaration
  • add the enum type in your class declaration
  • register your enum name using the Q_ENUM macro in your class declaration
  • register the enum type name to the property using the Property::setEnumTypeName
Anywhere in your code use the property(..).toInt() method to get the classical enum value of the property, and use Property::getEnumValueAsString() to get the enum value as a string. If you declared your enum using Q_ENUM (Qt>=5.5), you can also use directly QMetaEnum::fromType to retrieve the enum value as strings (see below).

You can change the enum value names in the GUI using the "enumNames" attributes. There is also a way to automatically build nicer enumNames (see below).

Enum icons might be set using Property::setEnumIcons.

For instance in the header:

class MyAction : public camitk::Action {
// Really needed! (replace ‗ by _ in your code if you copy-paste this snippet)
Q‗OBJECT
// declare the C++ enum
enum MyEnum {
PossibleValue1,
PossibleValue2
};
// register the enum (Qt >= 5.5)
Q_ENUM(MyEnum)
...
private:
// the enum property
Property *enumProp;
};
Action class is an abstract class that enables you to build a action (generally on a component).
Definition: Action.h:209

And then in the code:

MyAction::MyAction(ActionExtension * extension) : Action(extension) {
...
// build the dynamic prop based on the enumeration
enumProp = new Property("My Enumeration", MyAction::PossibleValue2, "Enumeration support example","");
// register the enum type name for automatically manage the enum as a popup list
enumProp->setEnumTypeName("MyEnum",this);
// The Property class automatically build the enum names presented to the user in the GUI
// (it will changed the enum literals to get a cleaner look, e.g. PossibleValue1 becomes "Possible Value 1")
// OR
// Set the enum names of your choice, using the enumNames property:
// enumProp->setEnumTypeName("MyEnum");
// QStringList propGUIName;
// propGUIName << "Possible Value #1" << "Possible Value #2";
// enumProp->setAttribute("enumNames", propGUIName);
// register the new prop as an action parameter
addParameter(enumProp);
}
...
// get the value as classical C++ enum
MyEnum enumPropCurrentValue = (MyEnum) property("My Enumeration").toInt();
// get the value as a QString (either "PossibleValue1" or "PossibleValue2", beware: this is different from the GUI names)
QString enumPropAsString = enumProp->getEnumValueAsString(this);
// Or thanks to Q_ENUM declaration:
QMetaEnum metaEnum = QMetaEnum::fromType<EnumerationExample>();
QString enumPropAsStringDirect = metaEnum.valueToKey(enumPropCurrentValue);
Note
This is not exactly a decorator pattern, as the Property class is not abstract. The Qt Meta Object is still held by the QtObject inherited class (e.g. Component or Action). The camitk::Property class adds description, readOnly status and specific attributes to a QObject dynamic property.

Constructor & Destructor Documentation

◆ Property()

camitk::Property::Property ( QString  name,
const QVariant &  variant,
QString  description,
QString  unit 
)

Constructor.

The variant parameters also allows you to initialize the value of the property. By default a Property is enabled and editable (i.e. by default it is not read-only)

Parameters
nameproperty name (unique identifier of your class property
variantspecify the property type (QVariant) and initial value
descriptiona sentence or two to describe the property (and its unit if any), can be Rich Text
unita unit of measurement (in SI unit), use symbols from https://en.wikipedia.org/wiki/SI_base_unit or https://en.wikipedia.org/wiki/SI_derived_unit when possible

References description.

◆ ~Property()

virtual camitk::Property::~Property ( )
virtualdefault

Destructor.

Member Function Documentation

◆ getAttribute()

QVariant camitk::Property::getAttribute ( QString  attName)

get the current value of a given attribute, see setAttribute() if the attribute attName was never set using setAttribute(), the return QVariant is invalid.

To test if a QVariant is invalid, use the QVariant::isValid() method e.g.: if (!myProp.getAttribute("bad").isValid()) { CAMITK_INFO(tr("myProp does not have an attribute 'bad' (or this attribute is still equals to the default value)")) }

It is recommended to only use this method inside a foreach(QString s: getAttributeList())

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties().

+ Here is the caller graph for this function:

◆ getAttributeList()

QStringList camitk::Property::getAttributeList ( )

returns the list of attribute names that are specific to this property

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties().

+ Here is the caller graph for this function:

◆ getDescription()

const QString & camitk::Property::getDescription ( ) const

get the description

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties().

+ Here is the caller graph for this function:

◆ getEnumIcons()

QMap< int, QIcon > camitk::Property::getEnumIcons ( ) const

get the enum icons

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties().

+ Here is the caller graph for this function:

◆ getEnumTypeName()

QString camitk::Property::getEnumTypeName ( ) const
Returns
the name of the Qt registered enum if the property's type is an enum, the null string otherwise (can be tested against QString isNull() method)

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties().

+ Here is the caller graph for this function:

◆ getEnumValueAsString()

QString camitk::Property::getEnumValueAsString ( const QObject *  objectDeclaringTheEnum) const

Utility method to get the current property value as a string.

The string corresponds one of the enum values: not the gui enum values set using setAttribute("enumNames"...)

If the property's type is an enum, this is the string corresponding to its value (the property value can be accessed, the normal way using the QVariant toInt() to get the int value (classical C++ enum value)

Parameters
objectDeclaringTheEnumis a pointer to the object instantiated from the class that declared the enum
Returns
the enum value as QString.

◆ getGroupName()

QString camitk::Property::getGroupName ( ) const

get this property subgroup's name

Returns
the group name or the null QString if no group were set, it can be tested with QString::isNull().

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties().

+ Here is the caller graph for this function:

◆ getInitialValue()

const QVariant & camitk::Property::getInitialValue ( ) const

return the initial (default) value

Referenced by camitk::Action::addParameter(), CamiTKPropertyList::addProperty(), camitk::PropertyObject::addProperty(), and camitk::Component::addProperty().

+ Here is the caller graph for this function:

◆ getName()

◆ getProperty()

Property * camitk::Property::getProperty ( QObject *  object,
QString  name 
)
static

get the camitk::Property decoration of a named property of the given QObject or nullptr if object does not have any camitk::Property

Note
If object is an instance of a class that declares a Q_INVOKABLE getProperty(QString) method, it means that a Qt Property "decoration" was stored. In this case, this method returns the result of getProperty(name) (i.e., it is expected that the result won't b nullptr if the named property is found.
Parameters
objectThe QObject to check
nameThe property name to look for
Returns
the pointer to the camitk::Property corresponding to the CamiTK Property of the named property

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties(), and camitk::PersistenceManager::fromProperties().

+ Here is the caller graph for this function:

◆ getReadOnly()

bool camitk::Property::getReadOnly ( ) const
Returns
true only if this property is read-only

Referenced by camitk::ObjectControllerPrivate::addDynamicProperties(), and camitk::PersistenceManager::fromProperties().

+ Here is the caller graph for this function:

◆ setAttribute()

void camitk::Property::setAttribute ( const QString &  attribute,
const QVariant &  value 
)

Set a given property for this attribute.

Note that not all the attributes are not usable for all property type (see table above). The supported attribute names are (see QtVariantPropertyManagerPrivate() constructor):

  • "maximum"
  • "minimum"
  • "singleStep"
  • "decimals"
  • "constraint"
  • "enumNames"
  • "regExp"
Parameters
attributename of the attribute
valuevalue of this attribute

Referenced by AnglesAndTranslationAction::AnglesAndTranslationAction(), AnisotropicDiffusion::AnisotropicDiffusion(), CannyEdgeDetection::CannyEdgeDetection(), ChangeParent::ChangeParent(), CleanPolyData::CleanPolyData(), camitk::InteractiveViewer::createProperties(), Decimation::Decimation(), Derivative::Derivative(), FillWithPoints::FillWithPoints(), GaussianFilter::GaussianFilter(), ManualThreshold::getWidget(), ResampleAction::getWidget(), MeshProjection::getWidget(), SimpleElastixRegistrationAction::getWidget(), GradientMagnitudeRecursiveGaussian::GradientMagnitudeRecursiveGaussian(), ICPRegistration::ICPRegistration(), ImageReconstructionAction::ImageReconstructionAction(), LaplacianRecursiveGaussian::LaplacianRecursiveGaussian(), ManualThreshold::ManualThreshold(), MeanFilter::MeanFilter(), MedianFilter::MedianFilter(), MergeMeshs::MergeMeshs(), MeshProjection::MeshProjection(), MorphologicalOperators::MorphologicalOperators(), OtsuFilter::OtsuFilter(), PixelColorChanger::PixelColorChanger(), ResampleAction::ResampleAction(), setEnumTypeName(), ShowFrame::ShowFrame(), SimpleElastixRegistrationAction::SimpleElastixRegistrationAction(), SmoothFilter::SmoothFilter(), SphereTopology::SphereTopology(), and WarpOut::WarpOut().

+ Here is the caller graph for this function:

◆ setDescription()

void camitk::Property::setDescription ( QString  description)

set the description (can be rich text)

References description.

◆ setEnumIcons()

void camitk::Property::setEnumIcons ( const QMap< int, QIcon > &  enumIcons)

set the icons for all the enums

◆ setEnumTypeName() [1/2]

void camitk::Property::setEnumTypeName ( QString  enumTypeName,
QObject *  objectDeclaringTheEnum 
)

if the property's type is an enum, set the name of the registered Qt Enum AND automatically build the enum names that will be used in the GUI.

There is no need to set the "enumNames" attribute, the enum names will automatically be build from the enum literals:

  • all words will be capitalized
  • all "_" (underscore) will be transformed to space
Parameters
enumTypeNamethe enum type name as declared in the header file
objectDeclaringTheEnumis a pointer to the object instantiated from the class that declared the enum

References setAttribute(), and setEnumTypeName().

+ Here is the call graph for this function:

◆ setEnumTypeName() [2/2]

void camitk::Property::setEnumTypeName ( QString  nameOfTheEnum)

if the property's type is an enum, set the name of the registered Qt Enum.

The enum names that will appear in the GUI will have to be given by setting the "enumNames" attribute.

Referenced by AnglesAndTranslationAction::AnglesAndTranslationAction(), AnisotropicDiffusion::AnisotropicDiffusion(), ChangeParent::ChangeParent(), ComputeCurvatures::ComputeCurvatures(), camitk::InteractiveViewer::createProperties(), Derivative::Derivative(), GaussianFilter::GaussianFilter(), ICPRegistration::ICPRegistration(), MeshProjection::MeshProjection(), MorphologicalOperators::MorphologicalOperators(), ResampleAction::ResampleAction(), setEnumTypeName(), and SimpleElastixRegistrationAction::SimpleElastixRegistrationAction().

+ Here is the caller graph for this function:

◆ setGroupName()

void camitk::Property::setGroupName ( QString  groupName)

Set the group name.

Properties can be separated into subgroups. Just set the group name and they will be arranged/classified by group.

Parameters
groupNamename of the group for this property

◆ setReadOnly()

void camitk::Property::setReadOnly ( bool  isReadOnly)

set this property as read-only

Referenced by CenterMesh::CenterMesh(), ConnectedComponents::ConnectedComponents(), ResampleAction::getWidget(), PMLComponent::initDynamicProperties(), camitk::MeshComponent::initDynamicProperties(), OtsuFilter::OtsuFilter(), camitk::ImageComponent::setImageData(), and SimpleElastixRegistrationAction::SimpleElastixRegistrationAction().

+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: