1

I've been using QQmlListProperty in a kind of a "master class" that is both in the same time a model and a qml list property, allowing the easy declarative markup of object backbones, which may or may not be modifiable as well as the runtime generation / consolidation of code from dynamic structure. I've shared something approximate in this answer.

I have zero idea of the actual implementation details, but what triggers my "spider sense" is the following bits of documentation:

QQmlListProperty::QQmlListProperty(QObject *object, QList<T *> &list) - the one I am currently using states that:

Generally this constructor should not be used in production code, as a writable QList violates QML's memory management rules.

The reason I implement QQmlListProperty is that I want to use the qtquick parser/factory or whatever to be able to create my model data from regular QML code. Naturally, the absence of insert and remove methods from the QQmlListProperty API on its own is not any cause of concern, as such functionality is not needed for the intended purpose, which is parse code and create objects as you go, for that appending suffices. The cause of my concern is the "writable QList violates QML's memory management rules" as the end result will later be modified. Not that appending doesn't qualify as writing too but still, I am worried about possible negative effects of "violating QML's memory management rules". Especially after the problems with objects being destroyed while still in use I stumbled upon.

In the general case, it seems that it is possible and not problematic to make runtime changes to the structure, created by parsing QML files, even if it has ids, for example:

  Rectangle {
    width: 50
    height: 50
    Rectangle {
      id: c
      width: 10
      height: 10
      color: "red"
    }
    Rectangle {
      y: 20
      width: 10
      height: 10
      color: "red"
    }
    Component.onCompleted: c.destroy()
  }

however in some cases it does say that the object can't be destroyed dynamically or something like that.

So am I safe to create object structures from QML files by implementing QQmlListProperty and making changes to those structures later on in light of the vague "writable QList violates QML's memory management rules" warning?

Community
  • 1
  • 1
dtech
  • 47,916
  • 17
  • 112
  • 190
  • I am not quite sure I understand. The QQmlListProperty is a type for handling things like the "children" property, i.e. to hold objects instantiated in QML as code blocks. It is not a list as a arbitrarily modifiybale sequential container. The engine only needs to append to such a kind of property when it processes the element definitions, one cannot "edit" the QML code on the fly and "insert" elements. – Kevin Krammer Sep 21 '16 at 19:52
  • I have to admit I don't really understand the mentioned warning in the Qt documentation, a custom set of functions would be doing exactly the same things as the ones registered by the constructor taking the QList reference – Kevin Krammer Sep 21 '16 at 19:52
  • @KevinKrammer - the idea is that this hybrid solution allows for a lot of flexibility - you can have a "objects instantiated in QML as code blocks" prototype, but then modify it, or create an arbitrary structure, which will compile itself to "objects instantiated in QML as code blocks" for later reuse. The project uses extensive code generation and allows the user to add to the program structure using a system for visual node programming during the runtime. The program can modify its own code on the fly and new code. – dtech Sep 21 '16 at 19:56
  • Take QML's `ListModel` for example - it seems to be legal to define an initial model using `ListElement {}` but then insert or remove arbitrary indices dynamically, even though the model is defined as "objects instantiated in QML as code blocks". – dtech Sep 21 '16 at 20:13
  • But ListModel doesn't use QQmlListProperty. The ListElements are processed using a "custom parser" to allow QML element/property like syntax but not requiring to actually have that type. This technique is also used by e.g. PropertyChanges, so that any property name can be specified. See https://www.kdab.com/qml-engine-internals-part-4-custom-parsers/ – Kevin Krammer Sep 21 '16 at 20:55
  • @KevinKrammer I haven't looked into the implementation. But I hope the intent is clear - my class implements `QQmlListProperty` so it can be created in and from QML code. With the added benefit it can be directly used as a model to draw a gui of it, where it can be modified. – dtech Sep 21 '16 at 20:59
  • I obviously don't know your use case but it sounds like you are trying to shoe-horn something into QQmlListProperty that is outside its use case, e.g. something like ListModel and ListElements. ListModel uses a syntax similar to child elements to allow for in-line values, but it doesn't have actual children object that it would need to handle via a QQmlListProperty. Which allows it to offer a manipulation API as well, since the initial data is just stored inside the model like any other data can can added/removed/modified at runtime – Kevin Krammer Sep 21 '16 at 21:11
  • Well, you make it sound like the use case is "handling things like the "children" property, i.e. to hold objects instantiated in QML as code blocks" to quote you. That's exactly what I am using it for. I need objects to be instantiated from QML code, and then modify those objects. Naturally, the "arbitrary writing" part takes place after the objects have been created, and yes, when code is parsed and objects are created you only need to append. My question is whether something can go wrong afterwards as an implication of the " writable QList violates QML's memory management rules" – dtech Sep 21 '16 at 21:18
  • OK, did a major refactoring of the question, hopefully now the problem is more obvious. – dtech Sep 21 '16 at 22:19
  • I don't think there is any issue with changing the objects themselves, my guess is that the documentation meant that it would be problematic if the C++ code would be changing the QList behind the scenes. However, even an implementation based on explicit append/count/clear functions could change the underlying storage behind the QML engine's back and would be equally wrong in doing so. I would say that as long as one doesn't do anything that violates the QQmlListProperty invariants, such as adding or removing elements from the container in C++, backing the property by a QList reference is OK – Kevin Krammer Sep 23 '16 at 19:01
  • @KevinKrammer - that's what I am doing - after the object tree is created from QML code, objects can be added or removed. It would be nice if you could elaborate on the "violates the QQmlListProperty invariants" thing. How long does the functionality of QQmlListProperty stay relevant? Isn't it basically irrelevant once the code is parsed and the objects are created? Why would modifying that structure afterwards be problematic? Removing from or adding to object trees, produced from QML code itself is not labeled as dangerous, and it all uses QQmlListProperty everywhere. – dtech Sep 23 '16 at 19:12
  • I just meant that this is my interpretation of the warning in the documentation, because it doesn't make much sense to me otherwise. A `Repeater` will likely have to manipulate its parent's `children` somehow when it removes/adds delegate instances. But it might do additional stuff, maybe some form of notification or changing the ownership status of objects, setting/unsetting the objects' parent item, etc. Without any deeper investigation my assumption would have been that the allows operations are the 4 specified ones: count/at/append/clear – Kevin Krammer Sep 23 '16 at 19:29
  • The objects are all data objects, strictly non-visible. So far it seems to work fine without issues, and that's for massive trees of tens of thousands of objects, I am able to insert and remove without any complications. I guess I will just have to wait and see if any issues pop up. Or maybe it is just a piece of incorrect or outdated documentation. I'd hate to write my own parser/factory in addition to all the other bugs and limitations I had to work around. – dtech Sep 23 '16 at 21:31

0 Answers0