[Development] Programmable delegate selection for QML views

Pierre-Yves Siret py.siret at gmail.com
Mon Aug 6 15:34:00 CEST 2018


2018-08-06 14:22 GMT+02:00 Mitch Curtis <mitch.curtis at qt.io>:

>
>
> > -----Original Message-----
> > From: Development <development-bounces+mitch.curtis=qt.io at qt-
> > project.org> On Behalf Of Paolo Angelelli
> > Sent: Monday, 6 August 2018 1:43 PM
> > To: development at qt-project.org
> > Subject: [Development] Programmable delegate selection for QML views
> >
> > Hi,
> >
> > as some of you might have noticed, it's several months that some are
> trying
> > to remove a long-standing limitation of the current QtQuick
> architecture: the
> > inability to dynamically select, at runtime, the delegate to use in a
> view,
> > based on whatever approach, either data-driven (typically using row data,
> > index, etc), or else.
> >
> > The workaround, so far, has been to use a Loader for this.
> > The Loader approach has several notable drawbacks, most importantly
> > - performance, under different situations
> > - it can only nest (and thus load) QQuickItems, being a QQuickItem itself
> >
> >
> > 3 possible solutions to this problem have been suggested in the past few
> > months, but it seems that no consensus has been reached on what is the
> > way to go.
> > So what i want to present, in this message, is an overview of these
> proposed
> > solutions, to:
> > - understand what is the general preference among the proposed
> > approaches
> > - see if anyone has other approaches to suggest, that might have been
> > overlooked so far
> >
> > Currently suggested solutions are all based on a so-called "delegate
> chooser"
> > (or selector), that would be queried whenever a delegate is required.
> > The differences are in how to provide such an element to the view from an
> > API perspective:
> >
> > 1. Add a new property to all view classes (ListView, TableView, ***View
> > etc.), where to specify the chooser.
> >    The delegate property would be used as fallback, if chooser not
> present.
> >    ( https://codereview.qt-project.org/206670/ )
> >
> > 2. Make the chooser subclass QQmlComponent, and pass it through the
> > delegate property in place of a regular delegate
> >    ( https://codereview.qt-project.org/228909/ , example usage
> > https://github.com/paoletto/MIVQVariant ).
> >
> > 3. Do not make the chooser subclass QQmlComponent.
> >    Instead, use another separate base class, like some
> > QQmlAbstractComponentSet.
> >    Then mangle things enough so that it could still be passed through the
> > delegate property.
> >    Reason for 3. (as alternative to 2.) is that there's one school of
> thought that
> > see such a chooser not as a QQmlComponent subclass, while still trying to
> > avoid an additional property.
>
> From reading the comments of https://codereview.qt-project.org/#/c/228909/,
> I see that it was Simon that doesn't think it should be a QQmlComponent
> subclass. It would be good to hear more from him about this.
>
> >
> > Ideally, should there be a clear winner, targeting 5.12 could still be
> viable.
> > Thoughts?
>
> At a quick glance, if we can do it with the existing delegate property
> (#2), it would be nice. That's less complex than having two delegate
> properties.
>
> One minor problem with this is what we do when none of the delegates match
> the data type. #1 seems to cover this (https://codereview.qt-
> project.org/#/c/206670/8/src/qml/types/qqmldelegatemodel.cpp) by
> requiring that delegate also be implemented if a delegateChooser is
> provided. How does #2 account for it? I guess with #2 there should be a way
> to provide a "default" delegate, by e.g. leaving all properties
> (indexValue, roleValue) unset so that it acts a sort of wildcard?
>
> > _______________________________________________
> > Development mailing list
> > Development at qt-project.org
> > http://lists.qt-project.org/mailman/listinfo/development
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
>

> - it can only nest (and thus load) QQuickItems, being a QQuickItem itself
Loader can wrap QObject too. This works : Instantiator { Loader { QtObject
{} } }
http://doc.qt.io/qt-5/qml-qtquick-loader.html#sourceComponent-prop : "Since
QtQuick 2.0, Loader is able to load any type of object; it is not
restricted to Item types."

For me 2 and 3 seem to best fit the QML mentality, it's analogous to the
model property of views not necessarly being a QAbstractItemModel; it can
also be a QList<QObject*>, an int, a QVariantList, etc. and the magic is
done behind the curtains to work with all the different types.

> One minor problem with this is what we do when none of the delegates
match the data type. #1 seems to cover this (https://codereview.qt-
project.org/#/c/206670/8/src/qml/types/qqmldelegatemodel.cpp) by requiring
that delegate also be implemented if a delegateChooser is provided. How
does #2 account for it? I guess with #2 there should be a way to provide a
"default" delegate, by e.g. leaving all properties (indexValue, roleValue)
unset so that it acts a sort of wildcard?

A default delegate looks like the sensible way to go indeed.
But should we REQUIRE one ? Why can't we just not instantiate something
when no fitting delegate is found ? That's what I believe #1 is actually
doing.

I've not really followed all the development off this feature, but is there
a consensus about the choice mechanism of the delegates (vague syntax,
potential choice criteria)?
>From what I remember it would be based on either index or a role value.

For one of my project I've implemented a property editor with Loader and a
c++ helper.
Basically my helper was returning a list of properties with some info about
it: name, type, some additional info when needed (values of an enum).
The loader chose the correct source from the type, but it could chose a
different delegate for a specific property name.

Basically :

    if (propIngo.name == "myCustomProp")
        return myCustomComponent;
    switch (propInfo.type) {
        case "int": return intComponent;
        case "string": return stringComponent;
        // ...

Do we want to support this scenario or should we stick with simpler ones ?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20180806/a47551e2/attachment.html>


More information about the Development mailing list