javascript - 如何在 QML 中实现回调函数?

标签 javascript qt callback qml

我想在 QML 中使用回调功能(使用 Qt5.5.1)。当传感器值发生变化时,我想调用最后按下的按钮的功能。我使用标准 QML 对象,而不使用 cpp 类创建自定义 QML 对象。我什至让它运行起来,但我不明白为什么它会这样工作。

我希望我需要手动调用levelChanged_ButtonCallback,但这会导致 TypeError: Property 'levelChanged_ButtonCallback' of object QQuickItem_QML_22(0xd6ab18) is not a function。

只要级别发生变化,onPressed中绑定(bind)的函数就会被调用,这很好。每当按下按钮时也会调用它,这与计划不同,但并不重要。我主要担心的是,我不太明白该函数在哪里/如何调用,并且我不确定是否可能会发生不需要的行为。

(我添加了一个计时器来模拟传感器值。两个 MouseArea 仅在颜色和 btnId 上有所不同。在我的实际应用程序中,我当然为这些按钮使用 .qml 文件。)

这是“干净的代码”还是可能会导致问题? 有没有一种干净的方法可以仅使用 QML 来完成此操作,或者我是否需要通过 cpp 类创建自定义 QML 对象? 我没有找到使用信号/插槽执行此操作的方法,因为根据最后按下的按钮,应该连接不同的插槽。

Item {
    id: sensor
    property int level: 0
    property int levelTreshold: 3
    property var levelChanged_ButtonCallback

    Timer {
        running: true
        interval: 5000
        repeat: true
        onTriggered: {
            if (sensor.level == 0) {
                sensor.level = sensor.levelTreshold;
            }
            else {
                sensor.level = 0;
            }
            console.log("sensor changed to " + sensor.level);

            /* Not needed, but why? Causes error.*/
            //sensor.levelChanged_ButtonCallback();
        }
    }
}

MouseArea {
    width: 50
    height: 50
    property string btnId: "red"
    onPressed: {
        sensor.levelChanged_ButtonCallback = Qt.binding(function() {
            if (sensor.level >= sensor.levelTreshold) {
                console.log("Button pressed with force: " + btnId);
            }
            else {
                console.log("Button pressed no force: " + btnId);
            }
        });
    }
    onReleased: {
        sensor.levelChanged_ButtonCallback = Qt.binding(function() {
            console.log("No button pressed, do nothing on level change! Release by: " + btnId);
        });
    }

    Rectangle {
        anchors.fill: parent
        color: "red"
    }
}

MouseArea {
    x: 80
    width: 50
    height: 50
    property string btnId: "blue"
    onPressed: {
        sensor.levelChanged_ButtonCallback = Qt.binding(function() {
            if (sensor.level >= sensor.levelTreshold) {
                console.log("Button pressed with force: " + btnId);
            }
            else {
                console.log("Button pressed no force: " + btnId);
            }
        });
    }
    onReleased: {
        sensor.levelChanged_ButtonCallback = Qt.binding(function() {
            console.log("No button pressed, do nothing on level change! Release by: " + btnId);
        });
    }
    Rectangle {
        anchors.fill: parent
        color: "blue"
    }
}

最佳答案

如果您更改 QML 中的值,您可以使用 onPropertyChanged 插槽/函数检测到该值。这就是 Qt 的工作原理(信号和槽)。无需您自己调用它。

一种方法:

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Item {
        id: sensor
        property var lastActiveButton: undefined
        property int level: 0
        property int levelTreshold: 3
        property var levelChanged_ButtonCallback

        onLevelChanged:{
            if(lastActiveButton){
                var lastButtonString = lastActiveButton === mouseRed ? "red" : "blue"
                if(level >= levelTreshold) console.log("Button pressed with force: " + lastButtonString);
                else console.log("Button pressed no force: " + lastButtonString);
            }
            else{
                console.log("No button active...");
            }
        }

        Timer {
            running: true
            interval: 5000
            repeat: true
            onTriggered: {
                if (sensor.level == 0)  sensor.level = sensor.levelTreshold;
                else  sensor.level = 0;
                console.log("sensor changed to " + sensor.level);
            }
        }
    }

    MouseArea {
        id: mouseRed
        width: 50
        height: 50
        onPressed: sensor.lastActiveButton = this
        onReleased: sensor.lastActiveButton = undefined

        Rectangle {
            anchors.fill: parent
            color: "red"
        }
    }

    MouseArea {
        id: mouseBlue
        x: 80
        width: 50
        height: 50
        onPressed: sensor.lastActiveButton = this
        onReleased: sensor.lastActiveButton = undefined

        Rectangle {
            anchors.fill: parent
            color: "blue"
        }
    }
}

关于javascript - 如何在 QML 中实现回调函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57162148/

相关文章:

c++ - 类模板的静态方法的奇怪问题

qt - CMake : Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)

c - 将整数值转换为 void* 是回调中常用的范例吗?

javascript - ReactJS - 将对象键和值作为 props 传递给 div

javascript - Angular : function call as attribute value for directive

c++ - 如何在 Symbian Qt 上的单个 QMainWindow、多个嵌套 QWidgets 应用程序中拥有动态变化的菜单?

ios - Swift - 如何从模型中的 API 调用返回 json 对象以在 View Controller 中使用

android - 将与菜单相关的事件称为 "callback function"是否有意义?

javascript - Jest 测试经常失败,因为 Puppeteer 无法点击 DOM 中的元素

javascript - 加载异步JS然后调用函数?