Introduce helper for QML to allow creating QWidget hierarchies

Commit 1259c5768e410361bcd8b5cf0c2057a2ebabda83 in qtdeclarative removed the
ability to create QWidgets in QML by giving them the correct parent, which
requires calling QWidget::setParent instead of QObject::setParent. This patch
introduces a hook that will allow QtQml to give widgets a proper parent.

Change-Id: I84c57ca5032582c43e405219343d55ac9cf2ffa0
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
This commit is contained in:
Simon Hausmann 2013-11-29 13:21:38 +01:00
parent 463c559962
commit fc8adfea9f
6 changed files with 32 additions and 0 deletions

View File

@ -177,6 +177,7 @@ void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObj
void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
bool (*QAbstractDeclarativeData::isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int) = 0;
void (*QAbstractDeclarativeData::setWidgetParent)(QObject *, QObject *) = 0;
QObjectData::~QObjectData() {}

View File

@ -87,6 +87,7 @@ public:
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
static bool (*isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int);
static void (*setWidgetParent)(QObject *, QObject *); // Used by the QML engine to specify parents for widgets. Set by QtWidgets.
};
// This is an implementation of QAbstractDeclarativeData that is identical with

View File

@ -630,6 +630,9 @@ void QApplicationPrivate::initialize()
// needed for a static build.
qRegisterWidgetsVariant();
// needed for widgets in QML
QAbstractDeclarativeData::setWidgetParent = QWidgetPrivate::setWidgetParentHelper;
if (application_type != QApplicationPrivate::Tty)
(void) QApplication::style(); // trigger creation of application style
#ifndef QT_NO_STATEMACHINE

View File

@ -12779,6 +12779,14 @@ void QWidget::clearMask()
setMask(QRegion());
}
void QWidgetPrivate::setWidgetParentHelper(QObject *widgetAsObject, QObject *newParent)
{
Q_ASSERT(widgetAsObject->isWidgetType());
Q_ASSERT(!newParent || newParent->isWidgetType());
QWidget *widget = static_cast<QWidget*>(widgetAsObject);
widget->setParent(static_cast<QWidget*>(newParent));
}
QT_END_NAMESPACE
#include "moc_qwidget.cpp"

View File

@ -653,6 +653,8 @@ public:
virtual void resolveSamples() { }
#endif
static void setWidgetParentHelper(QObject *widgetAsObject, QObject *newParent);
// Variables.
// Regular pointers (keep them together to avoid gaps on 64 bit architectures).
QWExtra *extra;

View File

@ -439,6 +439,8 @@ private slots:
void resizeStaticContentsChildWidget_QTBUG35282();
void qmlSetParentHelper();
private:
bool ensureScreenSize(int width, int height);
QWidget *testWidget;
@ -10396,5 +10398,20 @@ void tst_QWidget::resizeStaticContentsChildWidget_QTBUG35282()
QVERIFY(childWidget.numPaintEvents >= 1);
}
void tst_QWidget::qmlSetParentHelper()
{
#ifdef QT_BUILD_INTERNAL
QWidget parent;
QWidget child;
QVERIFY(QAbstractDeclarativeData::setWidgetParent);
QAbstractDeclarativeData::setWidgetParent(&child, &parent);
QVERIFY(child.parentWidget() == &parent);
QAbstractDeclarativeData::setWidgetParent(&child, 0);
QVERIFY(!child.parentWidget());
#else
QSKIP("Needs QT_BUILD_INTERNAL");
#endif
}
QTEST_MAIN(tst_QWidget)
#include "tst_qwidget.moc"