Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# TQt Widget Hierarchy (in-process)

The ActiveX control in this example is a TQWidget subclass with child widgets that are accessible as sub types.

        class TQParentWidget : public TQWidget
        {
            TQ_OBJECT
        public:
            TQParentWidget( TQWidget *parent = 0, const char *name = 0, WFlags f = 0 );

            TQSize sizeHint() const;

        public slots:
            void createSubWidget( const TQString &name );

            TQSubWidget *subWidget( const TQString &name );

        private:
            TQVBoxLayout *vbox;
        };

The `TQParentWidget` class provides slots to create a widget with a name, and to return a pointer to a named widget.

        TQParentWidget::TQParentWidget( TQWidget *parent, const char *name, WFlags f )
        : TQWidget( parent, name, f )
        {
            vbox = new TQVBoxLayout( this );
            vbox->setAutoAdd( true );
        }

The constructor of TQParentWidget creates a vertical box layout. New child widgets are automatically added to the layout.

        void TQParentWidget::createSubWidget( const TQString &name )
        {
            TQSubWidget *sw = new TQSubWidget( this, name );
            sw->setLabel( name );
            sw->show();
        }

The `createSubWidget` slot creates a new `TQSubWidget` with the name provided in the parameter, and sets the label to that name. The widget is also shown explicitly.

        TQSubWidget *TQParentWidget::subWidget( const TQString &name )
        {
            return (TQSubWidget*)child( name, "TQSubWidget" );
        }

The `subWidget` slot uses the TQObject::child() function and returns the first child of type `TQSubWidget` that has the requested name.

        class TQSubWidget : public TQWidget
        {
            TQ_OBJECT
            TQ_PROPERTY( TQString label READ label WRITE setLabel )
        public:
            TQSubWidget( TQWidget *parent = 0, const char *name = 0, WFlags f = 0 );

            void setLabel( const TQString &text );
            TQString label() const;

            TQSize sizeHint() const;

        protected:
            void paintEvent( TQPaintEvent *e );

        private:
            TQString lbl;
        };

The `TQSubWidget` class has a single string-property `label`, and implements the paintEvent to draw the label.

        TQSubWidget::TQSubWidget( TQWidget *parent, const char *name, WFlags f )
        : TQWidget( parent, name, f )
        {
        }

        void TQSubWidget::setLabel( const TQString &text )
        {
            lbl = text;
            setName( text );
            update();
        }

        TQString TQSubWidget::label() const
        {
            return lbl;
        }

        TQSize TQSubWidget::sizeHint() const
        {
            TQFontMetrics fm( font() );
            return TQSize( fm.width(lbl), fm.height() );
        }

        void TQSubWidget::paintEvent( TQPaintEvent * )
        {
            TQPainter painter(this);
            painter.setPen( colorGroup().text() );
            painter.drawText( rect(), AlignCenter, lbl );
        }

The implementation of the TQSubWidget class is self-explanatory.

        class ActiveTQtFactory : public TQAxFactory
        {
        public:
            ActiveTQtFactory( const TQUuid &lib, const TQUuid &app )
                : TQAxFactory( lib, app )
            {}
            TQStringList featureList() const
            {
                TQStringList list;
                list << "TQParentWidget";
                list << "TQSubWidget";
                return list;
            }

The `ActiveTQtFactory` class implements a TQAxFactory. It returns the class names of all supported types, `TQParentWidget` and `TQSubWidget`, from the `featureList()` reimplementation.

            TQWidget *create( const TQString &key, TQWidget *parent, const char *name )
            {
                if ( key == "TQParentWidget" )
                    return new TQParentWidget( parent, name );

                return 0;
            }

The factory can however only create objects of the `TQParentWidget` type directly - objects of subtypes can only be created through the interface of `TQParentWidget` objects.

            TQUuid classID( const TQString &key ) const
            {
                if ( key == "TQParentWidget" )
                    return TQUuid( "{d574a747-8016-46db-a07c-b2b4854ee75c}" );
                if ( key == "TQSubWidget" )
                    return TQUuid( "{850652f4-8f71-4f69-b745-bce241ccdc30}" );

                return TQUuid();
            }
            TQUuid interfaceID( const TQString &key ) const
            {
                if ( key == "TQParentWidget" )
                    return TQUuid( "{4a30719d-d9c2-4659-9d16-67378209f822}" );
                if ( key == "TQSubWidget" )
                    return TQUuid( "{2d76cc2f-3488-417a-83d6-debff88b3c3f}" );

                return TQUuid();
            }
            TQUuid eventsID( const TQString &key ) const
            {
                if ( key == "TQParentWidget" )
                    return TQUuid( "{aac9f855-c3dc-4cae-b747-c77f4d509f4c}" );
                if ( key == "TQSubWidget" )
                    return TQUuid( "{25fac47e-c723-4696-8c74-6185903bdf65}" );

                return TQUuid();
            }

COM however requires the IDs for the interfaces of the sub types as well to be able to marshal calls correctly.

            TQString exposeToSuperClass( const TQString &key ) const
            {
                if ( key == "TQSubWidget" )
                    return key;
                return TQAxFactory::exposeToSuperClass(key);
            }
        };

Objects of the `TQSubWidget` type should not expose the full functionality of e.g. TQWidget. Only those properties and slots explicitly declared in the type are accessible.

        TQAXFACTORY_EXPORT( ActiveTQtFactory, "{9e626211-be62-4d18-9483-9419358fbb03}", "{75c276de-1df5-451f-a004-e4fa1a587df1}" )

The factory is then exported using the TQAXFACTORY_EXPORT macro.

To build the example you must first build the TQAxServer library. Then run qmake and your make tool in `examples/multiple`.

The demonstration requires your WebBrowser to support ActiveX controls, and scripting to be enabled.

        <script language=javascript>
        function createSubWidget( form )
        {
            ParentWidget.createSubWidget( form.nameEdit.value );
        }

        function renameSubWidget( form )
        {
            var SubWidget = ParentWidget.subWidget( form.nameEdit.value );
            if ( !SubWidget ) {
                alert( "No such widget " + form.nameEdit.value + "!" );
                return;
            }
            SubWidget.label = form.labelEdit.value;
            form.nameEdit.value = SubWidget.label;
        }

        function setFont( form )
        {
            ParentWidget.font = form.fontEdit.value;
        }
        </script>

        <p>
        This widget can have many children!<br>
        <object ID="ParentWidget" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c"
        CODEBASE=http://www.trolltech.com/demos/hierarchy.cab>
        [Object not available! Did you forget to build and register the server?]
        </object><br>
        <form>
        <input type="edit" ID="nameEdit" value = "<enter object name>">
        <input type="button" value = "Create" onClick="createSubWidget(this.form)">
        <input type="edit" ID="labelEdit">
        <input type="button" value = "Rename" onClick="renameSubWidget(this.form)">
        <br>
        <input type="edit" ID="fontEdit" value = "MS Sans Serif">
        <input type="button" value = "Set Font" onClick="setFont(this.form)">
        </form>

See also The TQAxServer Examples.