Qt QML Hot Tips #4
Mike Trahearn - Qt QML Hot Tips

Qt QML Hot Tips #4

Part 4 - May I See Your ID?

In this article I cover one of the easiest parts of the QML syntax - but its inclusion in this series mean, yep, I've seen some right clangers. You'd be surprised how "easy" it seems to be to go wrong with such a simple thing - because actually, it isn't.

Unfortunately for me, I never get asked for my ID when I visit certain stores for celebratory purposes (which I might do today being a significant career anniversary), since, well I ahem don't look young enough to be asked (sigh).

However, ID is very important in the language of QML and it is the primary way you figure out who someone (or rather property) belongs to. In C++ we have pointers and references, but in QML we have the id attribute. The id attribute is not a property but a special case where we give our QML object ad id by which we can reference it elsewhere.

Users of QWidgets may be all too familiar with the objectName string property which is of course available on all QML objects because it comes for free from QObject. You can easily set this in QML and is a great aid to debugging and also for tools like Squish to locate named objects if it can't get the id.

What's the big IDea?

Here's a contrived example which quickly demonstrates the difference between id and objectName:

import QtQuick // I'm assuming Qt 5.15+

QtObject {
  id: myObject // this is the id
  objectName: "myObject" // this is the objectName
  
  // now we can use the id to reference a property
  Component.onCompleted: console.log(myObject.objectName)
}        

Does everything need an id?

Yes. Mostly. Normally. It is definitely something you want to do. I mentioned this in an earlier article and we'll cover that very briefly here. If you create an instance of an object you want to reference then you'll probably want to give it an id. Reference? Like the above simple case, but we're also talking about making bindings to other objects or using properties of them in JavaScript functions.

But there are some notable exceptions

  • Components

When creating a component with the Component um, component... you give the Component the id rather than the component that it is wrapping. That's a mouthful, but here's the gist:

Component 
    id: myCustomObject
    
    MyCustomObject {
        // no id here
        // add your properties here
    }
}
    
Loader {
    sourceComponent: myCustomObject
}        

Note that properties on an object so declared above will only evaluate their bindings once the component is actually created as an object. Without being created, the component is only parsed and understood by the QQmlEngine, but not created. If you do give it an id to the component (e.g. in this case MyCustomObject), then you might be tempted to create bindings TO it, which won't work because the object in the lines of QML where it is declared are NOT an object instance, but the instructions that one may be created FROM - and hence we call it a component, not an object (element).

  • Model Delegates

You shouldn't really be trying to access any property belonging to a model delegate from outside that delegate because it is a really bad design pattern straight off, but importantly its lifetime is not guaranteed, not just because the model may change, but certain views e.g. ListView even recycle delegates for a really nice performance optimisation (which when I first saw it was one of those "hats off to whoever wrote that - Qt is awesome!" moments . If you need access to model data at a specific index then you should be looking at providing some Q_INVOKABLE methods on your model to do so. And be asking yourself why.

  • Style Delegates

This one is subtle. If like me you've spend a lot of time digging into Qt Quick Controls 2 and creating your own style suites, you'll have very quickly come across things like "background" and "contentItem". These are the visual implementations of the behaviour described by the template.

The QQmlEngine will create an instance of every component with an id.

The above statement is important when it comes to delegates within a styled component because you may well want to provide customisations to your new fancy component and consequently override for example the background delegate. In such a case, if your base style implementation delegate has an id, QML will create BOTH that one AND the the overriding one - which is a waste of time. If the style delegates don't have ids, they won't get created if the delegate property is overridden.

  • "Hidden" objects

You may wish for some reason to encapsulate and hide away some functions, bindings or other processing inside another component and it for whatever reason doesn't need an id because it is not referenced directly anywhere.

Don't you dare call me that...

There are some rules about ids:

1) can't have spaces or symbols

2) must start with a lower case letter.

3) they can't be any of the QML reserved keywords

4) must be unique within the QML file (which is called the context see below)

5) must be accessible within the context - don't you even think about referencing an object by its id if that object is declared outside of your immediate QML file (context). This "used to be allowed" in Qt 5 but no more. Such cases are called unqualified ids are now considered erroneous and without going into further detail, not only will the QML tooling shout at you but Ulf Hermann will personally shoot you with his "foot guns".

Bonus: Can you get the id from c++? Yes you can!

To get an object's id from C++ you must first get the QQmlContext that the object was created in:

QQmlContext *context = qmlContext(object);        

If the object implements QQmlParserStatus, then the QQmlContext is available during or after componentComplete() but not before.

QString id = context->nameForObject(object);        

You can also get the objectName too. Note that the objectName can also be set from c++ in which case it can be gotten soon after the object constructor. If the objectName is set from QML, then only after componentCompleted() occurs.

QString id = object->objectName();        

For More Reading

And some more examples of these and potential solutions coming up in the next article...

Furkan üzümcü

Senior Software Engineer

3 个月

Great points! > The QQmlEngine will create an instance of every component with an id. This will be the case if the style components have a nested component with an id as well. ``` Button { ???id: root ???background: Rectangle { ???????color: "red" ???????Item { ???????????id: it ???????} ???} } ```

要查看或添加评论,请登录

Mike Trahearn的更多文章

  • Qt QML Hot Tips #9

    Qt QML Hot Tips #9

    Part 9 - Move your QML over to the DARK side..

    11 条评论
  • #QtStories - My Experience. My Story. Your Future!

    #QtStories - My Experience. My Story. Your Future!

    The letters 'Q' and 't' have been at the core of my career and I would like to take a couple of moments to explain why.…

    6 条评论
  • Qt QML Hot Tips #8

    Qt QML Hot Tips #8

    Part 8 - How to save face by using namespaces - a quick guide to QML and enums! Following a rather extended period…

  • Qt QML Hot Tips #7

    Qt QML Hot Tips #7

    Part 7 - Does my RCC look BIG in this? Or, "How to handle your large assets"..

    1 条评论
  • Qt QML Hot Tips #6

    Qt QML Hot Tips #6

    Part 6 - The "Unbinding" Like sounding like a potential horror film title, this article is inspired by a shuddering…

    1 条评论
  • Qt QML Festive Hot Tips

    Qt QML Festive Hot Tips

    Ho Ho Hot Tips - Christmas Special! While your projects are getting stuffed and your turkey is still compiling I…

  • Qt QML Hot Tips #5

    Qt QML Hot Tips #5

    Part 5 - I'm sorry, your access is restricted! From Qt 5.15 and much more strictly in Qt 6, a series of improvements…

  • Qt QML Hot Tips #3

    Qt QML Hot Tips #3

    Part 3 - Are your properties required? if(someObjectProperty !== null) someObjectProperty.callFunction() is found…

    6 条评论
  • Qt QML Hot Tips #2

    Qt QML Hot Tips #2

    Welcome to Part 2! Continuing on a theme of raging against the tide of poorly written QML using examples from years of…

  • Qt QML Hot Tips #1

    Qt QML Hot Tips #1

    Welcome! This is the first of many extremely short articles containing some absolute nuggets of gold stashed away until…

    12 条评论

社区洞察

其他会员也浏览了