Re: [Development] QML, Widgets, and setParent
On Saturday 2. November 2013 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 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. > > > > 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. > > 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 > > 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 Just for reference on this mailing list, I propose the following fix for (3) that should restore the behavior of Qt 4: https://codereview.qt-project.org/#change,72847 Simon ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
On Tuesday 05 November 2013 06:48:11 Alan Alpert wrote: > 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. Correct, this example aborts. But not where you expect: it is caught in the DeclarativeWidgets lib itself. $ ./declarativewidgets test.qml Root Element is neither an AbstractDeclarativeObject nor a widget Aborted > 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... There is a lot of code handling layouts specially. If I reformat your example thusly: import QtWidgets 1.0 Widget { HBoxLayout { id: foo property Widget bar: Label{ text: "hello" } Label { text: "world" } } } The "world" label shows up, while the "hello" widget is ignored by the layout (the outer Widget is necessary because layouts cannot be shown on their own). Konrad signature.asc Description: This is a digitally signed message part. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
On Monday, 2013-11-04, 21:48:11, Alan Alpert wrote: > On Sat, Nov 2, 2013 at 5:06 AM, Kevin Krammer wrote: > > 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... Interesting, will have to try that. So far we've never used a widget as a named property, only ever as part of a declarative list property. Cheers, Kevin -- Kevin Krammer | kevin.kram...@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 smime.p7s Description: S/MIME cryptographic signature ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
On Sat, Nov 2, 2013 at 5:06 AM, Kevin Krammer 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 ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
On Saturday 02 November 2013, Kevin Krammer wrote: > 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); wow! You are absolutely correct. It works now. > > 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. No, I'm using a debug build of Qt4 and it works with that too. The idea above was the one that hit it. I basically restored Qt4 behavior to Qt5, but with a plugin to avoid the QtWidgets dependency. > 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. Yepp. That's it. Konrad signature.asc Description: This is a digitally signed message part. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
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.kram...@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 smime.p7s Description: S/MIME cryptographic signature ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
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 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. > > 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. 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 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 Konrad signature.asc Description: This is a digitally signed message part. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
On Thursday, 2013-10-31, 20:17:43, Konrad Rosenbaum wrote: > Hi, > > I'm trying to port KDAB's DeclarativeWidgets[1] to Qt5. Cool! > 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. > 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* Cheers, Kevin -- Kevin Krammer | kevin.kram...@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 smime.p7s Description: S/MIME cryptographic signature ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QML, Widgets, and setParent
I'd argue that it's setParent with the bug. It's conceptually valid to have a QWidget with a QObject parent but no QWidget parent, but it won't really show up until you try to use them in QML. If you do this with non-QML QWidgets, then it won't show up on screen so the user will think they've made an error (but with QML there's an intermediate state it goes through even in a correct usage case). QML as a language requires that you can set the QObject::parent on instances of QML types, so if that QObject assert is valid it means you can't use widgets in QML without hacks (specifically, that exact hack you found already which doesn't allow intermingling). -- Alan Alpert On Thu, Oct 31, 2013 at 12:17 PM, Konrad Rosenbaum wrote: > Hi, > > I'm trying to port KDAB's DeclarativeWidgets[1] to Qt5. 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); > > Apart from not understanding why there is a significant difference between > QObjects and QWidgets in regards to parenting... > > There used to be code that handled this in qqmlvme.cpp[2], but it has been > disabled by an #if 0 . Apparently to remove dependencies on QtWidgets from > QtQml. > > 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? > > > > Konrad > > > [1] It enables you to create widget based GUIs using QML. > git://github.com/KDAB/DeclarativeWidgets > > [2] In 5.2 beta this is line 627 in qqmlvme.cpp. It's Halloween. Go ahead, > look at scary code! ;-) > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development > ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development