__property
or [property].
Our solution works with
any standard C++ compiler on every platform we support. It's based on
the Meta Object System that also
provides object communication through signals and slots.
The Q_PROPERTY
macro in a class declaration declares a
property. Properties can only be declared in classes that inherit QObject. A second macro - Q_OVERRIDE
- can be used to override some
aspects of an inherited property in a subclass.
To the outer world, a property appears quite similar to a data member. However, properties have several features that distinguish them from ordinary data members:
Properties can be read and written through generic functions in QObject without knowing anything about class in use. These two are equivalent:
//QButton * b and QObject * o point to the same button b->setDown( TRUE ); o->setProperty( "down", TRUE );
Equivalent, that is, except that the first is faster, and that the first gives much better diagnostics at compile time. When accessible, the first is preferred. However, since you can get a list of all available properties for any QObject through its metaObject() setProperty() can give you control over classes that weren't available at compile time.
As well as QObject::setProperty(), there is a QObject::property(). QMetaObject::propertyNames() returns the names of all available properties. QMetaObject::property() returns the property data for a named property: a QMetaProperty object.
Here's a simple example that shows the most important property functions in use:
class MyClass : public QObject { Q_OBJECT public: MyClass( QObject * parent=0, const char * name=0 ); ~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow }; void setPriority( Priority ); Priority priority() const; };
The class has a property "priority" that is not yet known to the meta
object system. In order to make the property known, you have to
declare it with the Q_PROPERTY
macro. The syntax is as follows:
Q_PROPERTY( type name READ getFunction [WRITE setFunction] [STORED bool] [DESIGNABLE bool] [RESET resetFunction])
For the declaration to be valid, the get function has to be const and to return either the type itself, a pointer to it, or a reference to it. The optional write function has to return void and to take exactly one argument, either the type itself, a pointer or a const reference to it. The meta object compiler enforces this.
The type of a property can be everything QVariant provides or an
enumeration type declared in the class itself. Since MyClass
uses
the enumeration type Priority
for the property, this type has to be
registered with the property system as well. This way it will be
possible to set a value by name, like this:
obj->setProperty( "priority", "VeryHigh" );
Enumeration types are registered with the Q_ENUMS
macro. Here's the
final class declaration including the property declaration:
class MyClass : public QObject { Q_OBJECT Q_PROPERTY( Priority priority READ priority WRITE setPriority ) Q_ENUMS( Priority ) public: MyClass( QObject * parent=0, const char * name=0 ); ~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow }; void setPriority( Priority ); Priority priority() const; };
Another similar macro is Q_SETS.
Like Q_ENUMS,
it registers an
enumeration type but marks it in addition as "set", i.e. the
enumeration values can be or'ed together. An I/O class might have
enumeration values "Read" and "Write" and accept "Read|Write": Such an
enum is best handled with Q_SETS,
not Q_ENUMS.
The remaining keywords in the Q_PROPERTY
section are STORED,
DESIGNABLE
and RESET.
STORED
declares whether the property's value is stored in the
object. Stored makes only sense for writable properties. The default
value is true.
DESIGNABLE
declares whether this property is suited for
modification by a GUI designer program. The default is true
for
writable properties, otherwise false.
RESET
names a function that will set the property to its default
state (which may have changed since initialization). The function
must return void and take no arguments.
Copyright © 2000 Trolltech | Trademarks | Qt version 2.2.1
|