8

Similar to the this keyword in C++, I’d like to either have a QML element to pass itself into a JS function, or have it set a property on another element to itself. Is this possible?

For example:

Rectangle{
id:theParent

property var theElement

SomeElement{
id:theChild
   MouseArea {
        anchors.fill:parent
        onClicked: {
            someJsFunction(*whatGoesHere*)
            parent.theElement=*whatGoesHere*
        }
    }

Or, Consider this:

Rectangle{
id:theParent

property var theElement

SomeElement{
id:theChild
    }

Then, in SomeElement.qml:

Rectangle{
   MouseArea {
        anchors.fill:parent
        onClicked: {
            someJsFunction(*whatGoesHere*)
            parent.theElement=*whatGoesHere*
        }
}
}

In this case, the *whatGoesHere* would be the instance of SomeElement where these are being called from.

Is this possible in QML? I would think the id property would make sense, but according to the docs, you cannot query the value of the id field, and anyway the id wouldn't be available if my SomeElement was described in a separate file, and the whatGoesHere handling above appeared in that separate file rather than in a particular instance.

3 Answers 3

11

I have two complementary proposals :

First, for a single usage, pass the ID as it's basically a pointer to the item :

MouseArea {
    id: myClicker;
    onClicked: { callFunc (myClicker); }
}

Then if you need multiple items to share this behavior, that means you're using MVC so the ID will work exactly the same :

Repeater {
    model: 100;
    delegate: MouseArea {
         id: myClicker;
         onClicked: { callFunc (myClicker); }
    }
}

That is the classical part.

But to todo even better if you create your own components, keep in mind to create a 'self' helper property that does the 'this' job properly :

MouseArea { // component root definition
    id: base;

    property var self : base; // bind self on the I
}

Then use it like this :

Repeater {
    model: 100;
    delegate: MyComponent {
         onClicked: { callFunc (self); }
    }
}

Use this as often as you want !

Sign up to request clarification or add additional context in comments.

1 Comment

Nice solutions, do you have a recommendation for components defined in c++ and exposed via qmlRegisterType() ? Can a QObject* typed Q_PROPERTY that points to this be used?
0

Instance of your SomeElement is its id property value i.e. theChild. You can use it as this. No other built-in way exists as far as I can tell. But you can try to add your own QML item hierarchy with property which will return this.

Another way is to get children of some parent and use them. So you get children, locate the child you need and use that particular instance

3 Comments

Suppose I have many SomeElements and I want this functionality defined in SomeElement.qml not in-line as in my code. The id would then not be available inside the SomeElement.qml since it is not an instance (yet).
Add name to each SomeElement, get children of the parent(which contains those SomeElements) and find what you need by name. Then use. It's very simple
Sure, looping through all children of the parent is one way to do it, but I was hoping for direct access as per the implied behavior of my code above. But I suspect this isn't idiomatic in QML
0

If you define your element in a separate file, then you can simply assign an id and use it. It will be valid just within the context of that instance:

SomeElement.qml

Rectangle{
   id: thisElement
   MouseArea {
        anchors.fill: parent
        onClicked: {
            someJsFunction(thisElement);
            parent.theElement = thisElement;
        }
   }
}

2 Comments

If you have multiple SomeElements in another file, several instances, each will have its own ID. Are you saying that the onClicked is smart enough to replace the thisElement you have in the SomeElement.qml file with the eventual instance's ID as set in another file?
It wont replace anything: think of the two ids as two pointers pointing to the same object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.