Hierarchy Example (ActiveQt)▲
class
QParentWidget : public
QWidget
{
Q_OBJECT
Q_CLASSINFO("ClassID"
, "{d574a747-8016-46db-a07c-b2b4854ee75c}"
);
Q_CLASSINFO("InterfaceID"
, "{4a30719d-d9c2-4659-9d16-67378209f822}"
);
Q_CLASSINFO("EventsID"
, "{4a30719d-d9c2-4659-9d16-67378209f823}"
);
public
:
explicit
QParentWidget(QWidget *
parent =
nullptr
);
QSize sizeHint() const
override
;
public
slots:
void
createSubWidget(const
QString &
amp;name);
QSubWidget *
subWidget(const
QString &
amp;name);
private
:
QVBoxLayout *
m_vbox;
}
;
The QParentWidget class provides slots to create a widget with a name, and to return a pointer to a named widget. The class declaration uses Q_CLASSINFO() to provide the COM identifiers for this class.
QParentWidget::
QParentWidget(QWidget *
parent)
:
QWidget(parent),
m_vbox(new
QVBoxLayout(this
))
{
}
The constructor of QParentWidget creates a vertical box layout. New child widgets are automatically added to the layout.
void
QParentWidget::
createSubWidget(const
QString &
amp;name)
{
QSubWidget *
sw =
new
QSubWidget(this
, name);
m_vbox-&
gt;addWidget(sw);
sw-&
gt;setLabel(name);
sw-&
gt;show();
}
The createSubWidget slot creates a new QSubWidget with the name provided in the parameter, and sets the label to that name. The widget is also shown explicitly.
QSubWidget *
QParentWidget::
subWidget(const
QString &
amp;name)
{
return
findChild&
lt;QSubWidget *&
gt;(name);
}
The subWidget slot uses the QObject::findChild() function and returns the first child of type QSubWidget that has the requested name.
class
QSubWidget : public
QWidget
{
Q_OBJECT
Q_PROPERTY(QString label READ label WRITE setLabel)
Q_CLASSINFO("ClassID"
, "{850652f4-8f71-4f69-b745-bce241ccdc30}"
);
Q_CLASSINFO("InterfaceID"
, "{2d76cc2f-3488-417a-83d6-debff88b3c3f}"
);
Q_CLASSINFO("ToSuperClass"
, "QSubWidget"
);
public
:
QSubWidget(QWidget *
parent =
nullptr
, const
QString &
amp;name =
QString());
void
setLabel(const
QString &
amp;text);
QString label() const
;
QSize sizeHint() const
override
;
protected
:
void
paintEvent(QPaintEvent *
e) override
;
private
:
QString m_label;
}
;
The QSubWidget class has a single string-property label, and implements the paintEvent to draw the label. The class uses again Q_CLASSINFO to provide the COM identifiers, and also sets the ToSuperClass attribute to QSubWidget, to ensure that only no slots of any superclasses (i.e. QWidget) are exposed.
QSubWidget::
QSubWidget(QWidget *
parent, const
QString &
amp;name)
:
QWidget(parent)
{
setObjectName(name);
}
void
QSubWidget::
setLabel(const
QString &
amp;text)
{
m_label =
text;
setObjectName(text);
update();
}
QString QSubWidget::
label() const
{
return
m_label;
}
QSize QSubWidget::
sizeHint() const
{
QFontMetrics fm(font());
return
QSize(fm.horizontalAdvance(m_label), fm.height());
}
void
QSubWidget::
paintEvent(QPaintEvent *
)
{
QPainter painter(this
);
painter.setPen(palette().text().color());
painter.drawText(rect(), Qt::
AlignCenter, m_label);
}
The implementation of the QSubWidget class is self-explanatory.
#include
"objects.h"
#include <QAxFactory>
QAXFACTORY_BEGIN("{9e626211-be62-4d18-9483-9419358fbb03}"
, "{75c276de-1df5-451f-a004-e4fa1a587df1}"
)
QAXCLASS(QParentWidget)
QAXTYPE(QSubWidget)
QAXFACTORY_END()
The classes are then exported using a QAxFactory. QParentWidget is exported as a full class (which can be created ), while QSubWidget is only exported as a type, which can only be created indirectly through APIs of QParentWidget.
To build the example you must first build the QAxServer library. Then run qmake and your make tool in activeqt/hierarchy.
The demonstration requires your WebBrowser to support ActiveX controls, and scripting to be enabled.
&
lt;script language=
"javascript"
&
gt;
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;
}
&
lt;/
script&
gt;
&
lt;p&
gt;
This widget can have many children!
&
lt;/
p&
gt;
&
lt;object ID=
"ParentWidget"
CLASSID=
"CLSID:d574a747-8016-46db-a07c-b2b4854ee75c"
CODEBASE=
"http://www.qt-project.org/demos/hierarchy.cab"
&
gt;
[Object not
available!
Did you forget to build and
register
the server?]
&
lt;/
object&
gt;&
lt;br /&
gt;
&
lt;form&
gt;
&
lt;input type=
"edit"
ID=
"nameEdit"
value=
"&lt;enter object name&gt;"
/&
gt;
&
lt;input type=
"button"
value=
"Create"
onClick=
"createSubWidget(this.form)"
/&
gt;
&
lt;input type=
"edit"
ID=
"labelEdit"
/&
gt;
&
lt;input type=
"button"
value=
"Rename"
onClick=
"renameSubWidget(this.form)"
/&
gt;
&
lt;br /&
gt;
&
lt;input type=
"edit"
ID=
"fontEdit"
value=
"MS Sans Serif"
/&
gt;
&
lt;input type=
"button"
value =
"Set Font"
onClick=
"setFont(this.form)"
/&
gt;
&
lt;/
form&
gt;