[Development] On QML and keeping data alive.
Alan Alpert
416365416c at gmail.com
Fri Aug 16 02:12:32 CEST 2013
On Thu, Aug 15, 2013 at 8:51 AM, Charley Bay <charleyb123 at gmail.com> wrote:
> Rene wrote:
>>
>> Hi Qt developers
>>
>> A little over a year ago I raised a question on this list about
>> QSharedPointers and QML, and got a lot of debate started, which turned out
>> to be very illuminating.
>> (http://lists.qt-project.org/pipermail/development/2012-May/004049.html)
>
>
>>
>> <snip, now clarifying deeper problems, how QML fits in MVC>
>
>
>>
>> <snip>, Clearly I am talking about the difficulties of a database
>> application.<snip>,
>>
>> The key is that SHARED OWNERSHIP must take effect during the use of the
>> objects in question.
>>
>> <snip>,
>> Now the punch line...
>>
>> THE CONTROLLER
>> ===========================
>>
>> While I see is as the job of the model to query the database and serialize
>> the SQL response into Q_PROPERTIES, I am quite reluctant to wish that
>> objects in the model domain should store QSharedPointers and hence be
>> responsible for resources being locked in memory as long as their (shared)
>> parent keeps them stored.
>> Instead I see it as the job of the View/Controller to lay claim to
>> resources while they are in use. Why? Because the controller ultimately is
>> responsible for actually using the database resource for as long as the view
>> exists.
>>
>> So far I have surprised very few programmers. The MODEL queries and
>> serializes data and the CONTROLLER does the resource management deciding
>> when it is time to let go of database resources again.
>
>
> Agreed. IMHO, this is the only significant "design issue" we've run into
> with using the QAIM (and there have been discussions on this list in the
> past, I can look them up if anyone cares).
>
> A change-to-the-design with this consideration (where the "view" secures
> transient resources from the "model") could be done in a number of ways, I
> think. But, I think it's important.
>
>>
>> <snip>,
>> SUMMING UP
>> ===========================
>> By now I think you get the problem (and sorry for being overly verbose).
>> QtQuick items makes good views but bad controllers. QWidget based forms are
>> fairly good for both. <snip>,
>
>
> Mostly agree, although I also have issues with QWidget-QAIM, in that I want
> the "QModelIndex" to have "type-information" OR wholly-contain state, such
> as a QSharedPointer<>.
>
>> <snip, ASCII art, lifetime of database resources and objects>
>
>
>>
>> But that still leaves out difficult decisions. Continuing on our example,
>> let's see how a simple CompanyView.qml could work out, using typical QML
>> idioms:
>>
>> COMPANYVIEW.QML:
>> Item {
>> property Company company
>> Column {
>> Text { text: company.name; .... }
>> ListView {
>> model: company.employees <<<<<<<<< PROBLEM: What does this
>> mean?
>> ....
>> }
>> }
>> }
>>
>> PERSONVIEW.QML:
>> Text {
>> property Person person
>> text: person.name
>> }
>>
>> Look at the place where the ListView is bound to the companys employee
>> list. What exactly is being asked of the model here? The semantics are
>> unclear. Is QML asking the C++ model to load the employees and then forget
>> about the references? I.e. can the C++ model trust the controller to keep
>> and store references itself? Clearly the view is accessing the model
>> directly, and that leaves out the controller, which should have helped store
>> the reference in a guaranteed way.
>>
>> In all fairness, the problem would also exist in a QWidget scenario. But
>> QML is extra difficult, because MVC usage patterns in my opinion aren't
>> really clear yet. My current instinct commands that me to make the most
>> beautiful interface, i.e. one using QQuickListProperty, which is not very
>> intuitive when it comes to custom types, and doesn't give a lot of room for
>> dealing with the resource management situation.
>>
>> Just like last year, I wish for an enriching debate, hoping I have
>> demonstrated the need to think usage patterns into the API design.
>>
>> Best regards,
>> Rene Jensen
>>
>> P.S.: You can always design your way out of most problems, and in this
>> case I will probably end up doing just that. But I still wish to hear your
>> take on the problem, because I imagine that these issues have been solved
>> before.
>
>
> IMHO, this is a tricky problem, that is not just QAIM/MVC. Specifically, I
> think we're talking about "value-semantics" and "reference-semantics" for
> instances that bridge across the QML/C++ boundary. Of course, as Rene
> points out, this is a "screamingly-loud-issue" when it comes to database
> resources, which is the thrust of his post.
>
> In this case, "value-semantics" in the view ensure the database
> resources/objects can be released (and still be represented in the "view"),
> while "reference-semantics" in the view ensure the database
> resources/objects must persist (in-memory).
>
> I don't have specific suggestions (yet) on what to do. However, we have
> similar issues related to our "data-models" that bridge QML/C++, and even
> for other "many-to-many" instances that bridge the QML/C++ boundary (which
> comes up a lot in our designs when interfacing directly with
> hardware/instrumentation).
So is this a question about MVC in QML generically, or specifically in
the modelview types exposed?
They have separate answers. MVC in QML generically has the controller
split between C++ and QML, and you can get the references to work by
having a QML wrapper class around the datum which does addRef in the
constructor and dropRef in the destructor. Then the shared memory
management logic is defined in C++, but realized by QML so that the UI
object lifetimes have the effect you desire.
The answer for modelview types specifically is, sadly, not so good. We
don't have the right types in several ways, and we don't have the
right architecture for using swapping out types (like the views 2
discussion from Qt CS).
The mythical views 2 should cover this. One thing being considered
there was a mechanism for delegate lifecycle and data population
(perhaps called the controller?) to stand between the model and
delegate instantiation. Maybe this is showing that it could have finer
grained control of context properties/objects as well?
The mythical models 2 might also cover this. From the QtQuick side
we've considered (on a theoretical level) separate model classes for
the two usecases you brought up. A simple application using a GridView
for a static 20 items has different model/view needs than a view onto
a massive database that won't fit into memory. There should be some
basic model which is dead-simple and lightning-fast, for models that
are fully loaded into memory already, and then some advanced model
which is harder to use but supports those extra cases (like QAIM,
which does currently try to meet all cases). Maybe the advanced model
could have an additional delegate instance representing the context
object so that you can monitor the lifecycle?
Either way there eventually should be a way to have more control over
the model and delegate from QML, allowing the same sort of controller
split as in the generic case.
--
Alan Alpert
More information about the Development
mailing list