[Development] QML, Widgets, and setParent

Kevin Krammer kevin.krammer at kdab.com
Sat Nov 2 13:06:09 CET 2013


On Saturday, 2013-11-02, 11:25:07, Konrad Rosenbaum wrote:
> Hi,
> 
> On Saturday 02 November 2013, Kevin Krammer wrote:
> > On Thursday, 2013-10-31, 20:17:43, Konrad Rosenbaum wrote:
> > > I've got it running
> > > for trivial QML files, however as soon as there are child widgets the
> > > running program aborts.
> > > 
> > > The abort is caused by QObject::setParent, which contains this little
> > > gem: Q_ASSERT(!d->isWidget);
> > 
> > Hmm. The same code is in Qt4. I think it "works for me/us" because we are
> > building against our distribution's Qt packages which are release builds
> > and thus doesn't have the Q_ASSERT.
> 
> No, it works for you because the Qt4 QML code (qqmlvme.cpp) contains special
> code to handle Widgets - in Qt5 it was deactivated to remove the dependency
> on the QtWidget module.

The Qt4 code does not call setParent if the object is a widget and the parent 
is not, e.g. if the parent is a layout. Still seems to work quite well.

Maybe it would still work if the Qt5 code did something like this:
 
if (!o->isWidgetType)
    QQml_setParent_noEvent(o, parent);

> The code of QObject::setParent itself is absolutely identical (I didn't
> check all the lines of QObjectPrivate::setParent_helper though). Qt4
> contains the same Q_ASSERT.

Sure, what I was saying is that maybe it "works for me" because I am using a 
release built Qt4. Q_ASSERT is not part of release build object code.

> > > I kind of ran out of ideas on how to solve this. Should I consider
> > > setParent, qqmlvme or the direct use of QWidgets as a bug?
> > 
> > I agree with Alan on setParent() being in error, the problem is some
> > other areas rely on that. E.g. QWidget::parentWidget() does a
> > static_cast of parent() to QWidget*
> 
> Upon reading the code of QWidget a bit more I must conclude that this was
> done deliberately (both in Qt4 and Qt5). If widgets are supposed to be able
> to have non-widget parents, then this is one hell of a design bug that can't
> be easily fixed inside a single minor release.

The thing is that the widgets wouldn't have non-Widget parents, at least not 
in DeclarativeWidgets. The parent is either a widget or, most of the times, a 
layout. The layouts' addWidget methods reparent to their parent widget.

Therefore one option might be to just not call set parent on widget objects 
and let the list property code deal with reparenting.

> I'm coming to the conclusion that I have only three options:
> 
> 1) give up - I must say, I don't like this one ;-)
> 
> 2) do a work-around by giving all widget classes a QObject based wrapper in
> the framework: on the plus side this would need no changes to Qt, on the
> down side this would make it slower and use up significantly more memory

We had that (based on QMetaObjectBuilder) originally until somebody pointed us 
toward qmlRegisterExtendedType.
We still use that for types that cannot be default constructed, e.g. 
QDeclarativeContext.

> 3) fix qqmlvme.cpp somehow: the trickiest one, since reintroducing a
> dependency on QtWidgets is not an option; the solution would probably
> involve a plugin that is loaded if/when a widget is encountered there

Maybe it is enough not to call setParent for widgets, see above

Cheers,
Kevin
-- 
Kevin Krammer | kevin.krammer at kdab.com | Software Engineer
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel. Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322)
KDAB - Qt Experts - Platform-independent software solutions
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5918 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20131102/9a5e9d49/attachment.bin>


More information about the Development mailing list