Permalink
Browse files

qtcollider: optimize QcWidgetFactory::newInstance()

Most optimization comes from replacing a call to QMetaObject::invokeMethod()
with getting the QMetaMethod and calling its invoke() directly.
  • Loading branch information...
1 parent c7e6514 commit 66e7ede7cdde256ee411f13962f9a4dbe5fd59f7 @jleben jleben committed May 2, 2012
Showing with 34 additions and 20 deletions.
  1. +33 −15 QtCollider/QcWidgetFactory.h
  2. +0 −2 QtCollider/widgets/BasicWidgets.h
  3. +1 −3 QtCollider/widgets/QcScrollArea.cpp
@@ -25,6 +25,7 @@
#include "QcObjectFactory.h"
#include "QWidgetProxy.h"
+#include <QMetaMethod>
#include <QLayout>
template <class QWIDGET>
@@ -60,12 +61,37 @@ class QcWidgetFactory : public QcObjectFactory<QWIDGET>
}
}
- QObjectProxy *prox( proxy(w, scObject) );
-
- // check if parent arg is valid;
+ // NOTE: performance: it is completely equal if parent is passed
+ // in constructor, or set later, but for some reason it is cheaper
+ // if it is set here, before setting other stuff like geometry, etc.
QObjectProxy *parentProxy( arg[0].value<QObjectProxy*>() );
+ QWidget *parent = parentProxy ? qobject_cast<QWidget*>( parentProxy->object() ) : 0;
+ if( parent )
+ {
+ const QMetaObject *mo = parent->metaObject();
+ int mi = mo->indexOfMethod( "addChild(QWidget*)" );
+ bool ok;
+ if( mi >= 0 )
+ {
+ QMetaMethod mm = mo->method( mi );
+ ok = mm.invoke( parent, Q_ARG(QWidget*, w) );
+ if(!ok)
+ {
+ qcErrorMsg("Could not set parent!");
+ delete w;
+ return 0;
+ }
+ }
+ else
+ {
+ if(parent->layout())
+ parent->layout()->addWidget(w);
+ else
+ w->setParent( parent );
+ }
+ }
// set requested geometry
@@ -78,21 +104,13 @@ class QcWidgetFactory : public QcObjectFactory<QWIDGET>
w->setAcceptDrops( true );
- // set parent
+ // ensure visible:
- QWidget *parent = parentProxy ? qobject_cast<QWidget*>( parentProxy->object() ) : 0;
-
- if( parent ) {
+ if(parent && parent->isVisible()) w->show();
- // Ok, we have the parent, so stuff the child in
-
- const QMetaObject *mo = parent->metaObject();
- bool ok = mo->invokeMethod( parent, "addChild", Q_ARG( QWidget*, w ) );
+ // create the proxy:
- if( !ok ) w->setParent( parent );
-
- w->show();
- }
+ QObjectProxy *prox( proxy(w, scObject) );
return prox;
}
@@ -38,7 +38,6 @@ class QcDefaultWidget : public QWidget
Q_OBJECT
public:
QcDefaultWidget() { setLayout( new QcDefaultLayout() ); }
- Q_INVOKABLE void addChild( QWidget* w ) { layout()->addWidget(w); }
};
class QcHLayoutWidget : public QWidget
@@ -153,7 +152,6 @@ class QcCustomPainted : public QcCanvas, QcHelper
QcCustomPainted() {
setLayout( new QcDefaultLayout() );
}
- Q_INVOKABLE void addChild( QWidget* w ) { layout()->addWidget(w); }
protected:
// reimplement event handlers just so events don't propagate
virtual void mousePressEvent( QMouseEvent * ) {}
@@ -107,10 +107,8 @@ void QcScrollArea::setWidget( QObjectProxy *proxy )
void QcScrollArea::addChild( QWidget* w )
{
- if( widget() ) {
+ if( widget() )
w->setParent( widget() );
- w->show();
- }
}
QRectF QcScrollArea::innerBounds() const {

0 comments on commit 66e7ede

Please sign in to comment.