HomeHome

Properties


Qt provides a sophisticated property system similar to those shipped by some compiler vendors. However, as a compiler- and platform-independent library, Qt cannot rely on non-standard compiler features like __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 TrolltechTrademarks
Qt version 2.2.1