Q_PROPERTY Macro: Describing QObject Properties

Q_PROPERTY Macro Describing QObject Properties

The property facility gives us a choice of ways to access data members:

  • Directly, through the classic getters/setters (faster, more efficient)
  • Indirectly, through the QObject/QMetaObject interface (more generic)

Example 15.3. src/properties/customer-props.h

[ . . . . ]
class CustProps : public QObject {
 Q_OBJECT <-- 1

 /* Each property declaration has the following syntax:

 Q_PROPERTY( type name READ getFunction [WRITE setFunction]
 [RESET resetFunction] [DESIGNABLE bool]
 [SCRIPTABLE bool] [STORED bool] )
 */

 Q_PROPERTY( QString Id READ getId WRITE setId );
 Q_PROPERTY( QString Name READ getName WRITE setName );
 Q_PROPERTY( QString Address READ getAddress WRITE setAddress );
 Q_PROPERTY( QString Phone READ getPhone WRITE setPhone);
 Q_PROPERTY( QDate DateEstablished
 READ getDateEstablished
 WRITE setDateEstablished );
 Q_PROPERTY( CustPropsType Type READ getType WRITE setType );
 Q_ENUMS( CustPropsType ) ; <-- 2

 public:
 enum CustPropsType
 { Corporate, Individual, Educational, Government }; <-- 3

 CustProps(QObject *parent = 0, const QString name = QString());

 QString getId() const {
 return m_Id;
 }
[ . . . . ]
CustPropsType getType() const {
 return m_Type;
 }

 QString getTypeString() const;
 void setId(const QString &newId);
[ . . . . ]
// Overloaded, so we can set the type 2 different ways:
 void setType(CustPropsType newType);
 void setType(QString newType);
private:
 QString m_Id, m_Name, m_Address, m_Phone;
 QDate m_Date;
 CustPropsType m_Type;
};
[ . . . . ]
 

(1)macro required for moc to preprocess class

(2)special macro to generate string-to-enum conversion functions

(3)The enum type definition must be in the same class definition as the Q_ENUMS macro.

In Example 15.3, we have a customer class with a Qt property defined for each data member. The name of a property must not be the same as any data member name. We have adopted the common practice of giving each property that corresponds to a data member a name that is based on the corresponding data member name. If the data member is m_DataItem, the corresponding property is named DataItem. We discuss an example of a class that has properties that do not correspond to data members in Section 16.3.3.

Notice the enum CustPropsType that is defined in the public section of the class CustProps. Just above that definition, the Q_ENUMS macro tells moc to generate some functions for this property in the QMetaProperty to aid in string conversions for enum values.

The setters and getters are defined in Example 15.4. They are implemented in the usual way.

Example 15.4. src/properties/customer-props.cpp

[ . . . . ]
CustProps::CustProps(QObject *parent, const QString name)
 :QObject(parent) {
 setObjectName(name);
}

void CustProps::setId(const QString &newId) {
 m_Id=newId;
}
[ . . . . ]
void CustProps::setType(CustPropsType theType) {
 m_Type=theType;
}

/* Method for setting enum values from Strings. */
void CustProps::setType(QString newType) { <-- 1

 static const QMetaObject* meta = metaObject(); <-- 2
 static int propindex = meta->indexOfProperty("Type");
 static const QMetaProperty mp = meta->property(propindex);

 QMetaEnum menum = mp.enumerator(); <-- 3
 const char* ntyp = newType.toAscii().data();
 m_Type = static_cast(menum.keyToValue(ntyp));
}

QString CustProps::getTypeString() const {
 return property("Type").toString();
}
[ . . . . ]
 

(1)Overloaded version that accepts a string as an argument. Sets value to -1 if unknown.

(2)Because they are static locals, the initializations happen only once.

(3)This code gets executed each time.

The implementation of the overloaded function setType(QString) takes advantage of QMetaProperty's Q_ENUM macro to convert the QString to the proper enumerated value. To obtain the correct QMetaProperty object for an enum, we first get the QMetaObject and call functions indexOfProperty() and property() to find it. QMetaProperty has a function called enumerator() that you can use to convert strings to enums. If the given QString argument does not match one of the enumerators, the keyToValue() function will return the value -1.

Static Local Variables

Observe that we have declared the three local (block scope) variables, meta, propindex, and mp, to be static.

Each call to this function will require the same QMetaProperty object, so there is no need to have repeated calls to the QMetaObject functions require the iteration each time. static local variables are initialized only once, which is our intentionrepeated calls to this function will use the same QMetaProperty object to do the conversion. Using static local variables this way in a function can greatly improve the run-time performance for that function.[4]

[4] This depends on how expensive creating the objects are and how often the function is called.


QVariant Class Accessing Properties

Part I: Introduction to C++ and Qt 4

C++ Introduction

Classes

Introduction to Qt

Lists

Functions

Inheritance and Polymorphism

Part II: Higher-Level Programming

Libraries

Introduction to Design Patterns

QObject

Generics and Containers

Qt GUI Widgets

Concurrency

Validation and Regular Expressions

Parsing XML

Meta Objects, Properties, and Reflective Programming

More Design Patterns

Models and Views

Qt SQL Classes

Part III: C++ Language Reference

Types and Expressions

Scope and Storage Class

Statements and Control Structures

Memory Access

Chapter Summary

Inheritance in Detail

Miscellaneous Topics

Part IV: Programming Assignments

MP3 Jukebox Assignments

Part V: Appendices

MP3 Jukebox Assignments

Bibliography

MP3 Jukebox Assignments



An Introduction to Design Patterns in C++ with Qt 4
An Introduction to Design Patterns in C++ with Qt 4
ISBN: 0131879057
EAN: 2147483647
Year: 2004
Pages: 268

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net