[Development] QML, Widgets, and setParent

Alan Alpert 416365416c at gmail.com
Tue Nov 5 06:48:11 CET 2013


On Sat, Nov 2, 2013 at 5:06 AM, Kevin Krammer <kevin.krammer at kdab.com> wrote:
> 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 surprised this works. There's implicit QObject parenting built
into the language, for example:
QtObject {
     id: foo
     property Widget bar: Widget{}
}

Will automatically make foo the qobject parent of bar.

I'm not certain, but I think this happens before it gets assigned to
the property which might make any declarative widgets example using
layouts crash in debug builds...

--
Alan Alpert



More information about the Development mailing list