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

安德烈亚斯

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

我希望我需要手动调用levelChanged_ButtonCallback,但这导致TypeError:对象QQuickItem_QML_22(0xd6ab18)的属性'levelChanged_ButtonCallback'不是一个函数。

每当级别更改时,都会调用绑定到onPressed的函数,这很好。每当按下按钮时也会调用它,这不是计划中的事,但并不重要。我主要担心的是,我不太了解该函数的调用位置/方式,并且不确定是否会发生不必要的行为。

(我添加了一个计时器来模拟传感器值。两个MouseAreas仅在颜色和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"
    }
}
t4ggno

如果您在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"
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章