Re: [Development] QML, Widgets, and setParent

2013-12-05 Thread Simon Hausmann
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

2013-11-06 Thread Konrad Rosenbaum
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

2013-11-05 Thread Kevin Krammer
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

2013-11-04 Thread Alan Alpert
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

2013-11-02 Thread Konrad Rosenbaum
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

2013-11-02 Thread Kevin Krammer
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

2013-11-02 Thread Konrad Rosenbaum
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

2013-11-02 Thread Kevin Krammer
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

2013-10-31 Thread Alan Alpert
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