Skip to content

Avoiding marker interfaces

Sunday, 27 February 2005  |  Rich

I was talking Ian Geiser last night on IRC about ways to allow you to dynamically query KParts for their interfaces. This would for example allow you to avoid having to link special interface classes, or to use marker classes to identify your capabilities.

What I came up with is a use of QMetaObject to attach metadata to a class using the CLASSINFO macro. For good measure, I threw in an example of dynamically querying the available slots and calling one of them.

The following class definition includes a marker 'MyMetaInfo' that can be queried at run time.

class helloclassinfo : public KMainWindow
{
    Q_OBJECT
    Q_CLASSINFO( "MyMetaInfo", "This is demo meta-info" )
    
public:
    /**
     * Default Constructor
     */
    helloclassinfo();

    /**
     * Default Destructor
     */
    virtual ~helloclassinfo();
};

The code to query it is pretty simple:

    QMetaObject *mo = metaObject();

    // Find the marker interface
    QCString cs = mo->classInfo( "MyMetaInfo" );
    if ( !cs.isNull() ) {
        // Use the fetched meta-data
        new QLabel( cs, this, "hello label" );
        
        // Lookup a slot
        int index = mo->findSlot( "setCaption(const QString&)", true );
        if ( index != -1 ) {
            QUObject args[2] = { QUObject(), QUObject() };
            static_QUType_QString.set( &(args[1]), QString("This is a test") );
            qt_invoke( index, args );
        }
        
        // Query the list of slots since we can
        QStrList sl = mo->slotNames( true );
        for ( uint i = 0; i < sl.count(); ++i ) {
            printf( "%s\n", sl.at(i) );
        }
    }

This will set the caption to 'This is a test', print out a list of all the slots to stdout, and set the label to the content of the CLASSINFO macro. So, could this be a way to attach more information to our classes for KDE 4?