7

I have QML code, for example this code

Item {
    id:self;

    function update(){
        var visitFunc = self.applyUpdate;

        innerTraversal(self,visitFunc);
    }

    function reset(){
         var visitFunc = self.applyReset;
        innerTraversal(self,visitFunc);
    }

    function innerTraversal(obj, visitFun){
        console.log(typeof visitFun);

        if(obj!== self && visitFun && typeof visitFun ==="function")
           visitFun(obj);

        if(hasChilderns(obj)){
            var objChilderns = obj.children;

            for(var i=0 ; i< objChilderns.length ; i++){
                innerTraversal(objChilderns[i]);
            }
        }
    }

    function hasChilderns(obj){
        if(typeof obj.children !== 'undefined')
            return true;
        else
            return false;
    }

    function applyReset(obj){
        if(typeof obj.reset === 'function')
            obj.reset();
    }

    function applyUpdate(obj){
        if(typeof obj.update === 'function')
            obj.update();
    }
}

in normal javascript this works cool, but when I use this code in QML the bad thing is visitFun always has type of undefined, and it does not work..

any idea how to make this work ?

3 Answers 3

9

In QtQuick 2 you should be able to bind functions to properties using

Item {  //<-- declaration
  id : item
  property variant fun 
}
item.fun : Qt.binding(function(){doSomething()})  //<--defintion

item.fun // <-- invocation without braces 

So you could pass an object with a generic function as parameter.

In general, function overloading a can also be used to create a generic function for example to create a Button type:

---Button.qml
Item {
  function fun() {}  //<-- declaration (empty dummy)
  MouseArea {
    anchors.fill: parent
    onClicked: {
      fun();    //<-- invocation
    }
  }
}
---
---main.qml---
Button {
id: button
  function fun() {  //<-- defintion by overloading
    doSomething
  }
}
---

Clicking the button will activate its onClick handler and actually do something ;). Again, you would then pass the object with the generic function not the function itself.

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

1 Comment

So, what about handlers in the qml? something like onClicked is there a Function type?
1

In QML internals your "self" has type "QQuickItem", while normal JS object (created with "new Object()" or "{"prop" : "value"}", for example) has type QJsValue. And "self" isn't variable name, it's QML id, keep in mind that defference.

In QML the using of signals\slots or property bindings can be much more powerful rather than passing callback like in "normal" JS. The using of "typeof" is also bad practice (as far as I know in "normal" JS too), you can simply write something like:

// Or simply "return obj.children" - but function become useless than.
if(obj.children)
        return true;
    else
        return false;

But this code still useless - Item's property "children" in QML has type "list", it always exists.

So my conclusion - you should try to learn some QML basics before writing something.

2 Comments

Thank you I appreciate your answer, but passing functions as arguments is an essential part of JavaScript and I would like to use it instead of using signal/slots which is not portable to use the same code concept in other places. Also, I would like to keep checking for childern because this code maybe will be usable in other places or objects that is not an item type! and what I wrote is just a sample of what I try to do, but mainly the javascript code will be in standlone js file. I just need to know onething, does really QML support full javascript syntax or no
@CreativeCoder have you found a solution? I also want to pass a function as argument to a custom dialog component. Would be interesting to know how did you solve your case. Thanks in advance
0

You can add to your Item property that will hold array of callbacks.

Item {
    id:self;
    property var visitFunCallbacks: []
}

Then in CreateObject() function you can simply initialize this property with array with arrow function (something like this [() => console.log("Hey, I'm callback passed from outside!")]).

Please check this documentation page, hope it will help you. https://doc.qt.io/qt-6/qtqml-javascript-dynamicobjectcreation.html

Comments

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.