Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-72164

Deprecate grouped properties




      In a future version of the QML language, we can drop the concept of grouped properties. Grouped properties are problematic because they violate encapsulation by letting outer components access internals of their children. Grouped properties also are responsible for a lot of complexity in our QML implementation.

      To replace grouped properties, the objects being set up should be passed wholesale to the component being instantiated. Currently you can do the following:

      Text {
          font.bold: true

      This would be replaced with:

      Text {
          font: Font { bold: true }

      As the explicit specification of "Font" is redundant here, we can add a shorthand syntax for this, which would deliberately have different semantics than the current grouped properties:

      Text {
          font { bold: true }

      The straight dot syntax shown in the first example should be removed, though, to make it clear that the user is not initializing an existing object in place, but rather creating a new one.

      This would mean that all the current internals like anchors, font, etc. need to be createable from QML, and assignable. In turn we can then set up a policy to have those internals be nullptr by default, saving some effort on initialization.




      However, the most common use cases of grouped properties right now are anchors in Item and font in various text-related elements. Mandating a source-incompatible change for all of those may be too much. Therefore, another way out of this may be an explicit declaration of a property to be grouped:

      A {
          grouped property Font font
      Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged GROUPED)

      This would mean that the property in question can be accessed as grouped property like "font.bold: true", but it does not get an identity independent of the enclosing object anymore. Therefore, assigning "font: Qt.font(...)" would not replace the Font object, but rather invoke it's assignment operator or copy all its properties individually. This way, many of the inconsistencies could be resolved in an elegant way. In particular:

      RR {
          grouped property Rectangle rect: Rectangle { property int i: 5 }

      This would not retain the "i" property, as only the base rectangle would be copied, not the extension declared inline. Or, it wouldn't work at all as you'd call the equivalent of "*nullptr = QQuickRectangle(...)".

      A {
          Rectangle {
              id: rrr
              property int i: 5
          grouped property Rectangle rect: rrr

      rrr != rect after this, as Rectangle is not a value type and "!=" compares identity. Also, rect doesn't have a property i.

      If a property is not grouped, any grouped assignment would lead to a warning in 5.15, and be prohibited in QML 3. There are some open questions, though:

      A {
          // What exactly can we do with this? 
          // Proposal: Nothing, as "var" doesn't declare any properties
          grouped property var jsobj: ({ a : 5 })
          // Same?
          grouped property variant varobj
      RR {
          rect: Rectangle { y: 40 }
          // Allowed? Precedence? What if we do this with multiple levels of grouped properties from different files?
          rect.x: 50


        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.



              qt.team.quick.subscriptions Qt Quick and Widgets Team
              ulherman Ulf Hermann
              0 Vote for this issue
              17 Start watching this issue



                Gerrit Reviews

                  There are no open Gerrit changes