Am 04.02.2020 um 17:47 schrieb Volker Hilsheimer:
On 4 Feb 2020, at 16:12, Ville Voutilainen <ville.voutilai...@gmail.com> wrote:

On Tue, 4 Feb 2020 at 15:40, Volker Hilsheimer <volker.hilshei...@qt.io> wrote:
This works, but now you are encoding the visual hierarchy of the widgets in two 
places: when asking the presumed parent to create the widgets; and when setting 
up the layout, which might do things differently (esp once you start 
refactoring complex UIs).#
That's not a problem. The code simply behaves as if you would have used the 
current constructors that take a parent parameter.

Ownership transfers between different qt parents don't violate the invariant. 
And they continue to work just like before.

So how is the above usage of makeChild an improvement over calling operator new 
to instantiate your objects?

It's also clearer to see the parent child relationship.

And it switches what the easiest way to construct a object is. Currently it's less code to create a object without a parent, whereas with my patch and the deprecation enabled the easiest way to handle qt objects is via makeChild.


But that just means that QBoxLayout::addWidget(std::unique_ptr<>) has to behave 
imho saner in that edge case and actually delete the widgets that were added but 
never parented. (And I should really implement that to show how it would work.)

That seems like a terrible idea. One of the layout’s jobs is to set up the 
parent/child hierarchy so that you as a developer don’t have to.
I don't see how that idea changes that.

Iif the layout deletes widgets that were created without parent, instead of 
adding it to the correct parent, then that’s a change. You have to create 
widgets with parents, and add them to the layout (which might then add it to 
another parent, which at the very least introduces unnecessary overhead of 
ChildAdded/Removed event processing).

I didn't explain the behaviour well enough, so sorry for the confussion.

The layout takes care of the child widgets only if it never parented the widgets.

If the layout parented the widgets, either in setLayout or because the layout already had a parent, then those widgets are owned by the parent widget not by the layout. Or because the layout was added to a different layout that has a parent.

Essentially, if in the layout dtor the widgets don't have a parent, then those widgets are owned by the layout.

And I'm open to only do that for those widgets that were explicitly moved into the layout, though I have a slight preference to changing the existing behaviour.



Do we really want to make it harder for people to write UIs just because the 
resulting code doesn’t satisfy a C++ idiom?
It's not a question of satisfying idioms for the sake of satisfying
idioms, it's a question of avoiding bugs that we know
based on decades of experience to be difficult to avoid with raw pointers.

That’s my point:

I do not believe that the decades of experience we have with QObject’s 
parent/child model support the claim that it is inferior to using 
smart-pointers. It’s not something people constantly struggle with.

The problem is that you have to actually know what every method does, which isn't always obvious and is not always documented.



That doesn’t invalidate the suggestion that we should use smart pointers in Qt 
code, or in Qt APIs where we are not benefitting from QObject trees.


If you don’t care about the things that QObject/QWidget does for you, then 
don’t use QObject/QWidget. And if you do use QObject/QWidget and get a 
consistent object model from it, then I’m really not convinced that adding 
smart pointers to the API is making the code clearer, or in any way more 
explicit. It’s not like the ability of using std::unique_ptr means that people 
no longer have to be familiar with Qt’s basic concepts to use it correctly.
Correct, but if code moves a std::unique_ptr into a function call
argument, I know that ownership is transferred, by just glancing at
the code. With a raw pointer, I don't know that.

But ownership isn’t transferred if you call QLayout::addWidget; it is never 
transferred to the layout object - it might be transferred to the QWidget that 
the layout operates on.

Well, that's a matter of perspective. With the API I outlined, ownership is indeed transferred to the layout, which then either a) immediately transfers it to the widget, b) transfers it later on e.g. setLayout, c) if neither happens the layout owns the widgets.

Now, it's worth reiterating that this is a edge case. This is only about layouts that never ever get added to a widget hierarchy. That should be rare.

daniel
_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to