最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

qt - QML : how to pass javascript function as argument in another function - Stack Overflow

programmeradmin3浏览0评论

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 ?

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 ?

Share Improve this question asked Jan 14, 2015 at 14:36 Creative CoderCreative Coder 4181 gold badge6 silver badges15 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 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.

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 bee 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.

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

发布评论

评论列表(0)

  1. 暂无评论