QML状态不会改变C ++信号

时间:2013-10-17 04:11:56

标签: qt signals qml qtquick2

我很难理解QML状态概念。

我有以下代码:

import QtQuick 2.1
import QtQuick.Controls 1.0

Rectangle{
    id: myRectangle
    width: 500
    height: 120

    state: "init"

    Button {

        id: myBtn1
        text: "hello"
        anchors.right: parent.right
        anchors.rightMargin: 40
        anchors.verticalCenter: parent.verticalCenter
        onClicked: {
            console.log("trying to change state to myState "
            myRectangle.state = "customState"
        }
    }
    Button {
        id: myBtn2
        text: "bye"
        anchors.right: parent.right
        anchors.rightMargin: 40
        anchors.verticalCenter: parent.verticalCenter
        onClicked: {
            myCppObject.coolFunction()
        }
        visible: false
    }

    Connections {
        target: myCppObject
        onCoolSignal: {
            console.log("signal triggered")
            console.log("state before signal: " + myRectangle.state);

            myRectangle.state = "init";

            console.log("state after signal: " + myRectangle.state);
        }

    }

    states: [
            State {
                name: "init"
                PropertyChanges {
                    target: myBtn1
                    visible:true
                }
                PropertyChanges {
                    target: myBtn2
                    visible: false
                }
            },
            State {
                name: "customState"
                PropertyChanges {
                    target: myBtn1
                    visible: false
                }
                PropertyChanges {
                    target: myBtn2
                    visible: true
                }
            }
    ]
}

我的意思是,点击“myBtn1”后,此按钮将消失,“myBtn2”应显示。因此我使用描述的状态,它到目前为止它的工作!状态发生变化,标有“bye”的按钮可见。

在下一步中单击按钮“myBtn2”调用“myCppObject”的函数“coolFunction”,其唯一目的是发出一个名为“coolSignal”的信号 - 这也有效!  我的问题是我确实在控制台中得到了预期的输出,如:

signal triggered
state before signal: customState
state after signal: init

但“myBtn1”保持隐藏,“myBtn2”保持可见!所以国家并没有真正改变! 我对QML中的状态不了解的任何想法?

btw:如果我将myBtn2.onClick更改为myRectangle.state = "init";,则状态转换有效!但我真的需要它发生在自定义C ++信号上!

感谢提前提供任何帮助。

编辑: 我忘了说我不使用main.qml里面顶部写的源代码。它位于一个名为MyElem.qml的额外QML文件中,该文件用作listview的委托元素。这意味着在运行时,会加载多个MyElem,并且所有这些都具有相同的ID(myRectangle)。这是我没有看到任何视觉变化的原因吗?

2 个答案:

答案 0 :(得分:0)

Button 1中的onClick处理程序引用myGame而不是myRectangle。由于Connections中的信号仅将状态重置为init,因此您从未成功将myRectangle的状态更改为init以外的任何内容。输出中应该有一条关于引用不存在的对象的错误消息....

答案 1 :(得分:0)

我有一个类似的问题,在我的情况下,我通过添加属性bool isCustomState解决了它(如果你需要更多的2个状态你可以使用int)并给状态一个条件。然后通过酒店做任何chages。

import QtQuick 2.1
import QtQuick.Controls 1.0

Rectangle{
    id: myRectangle
    width: 500
    height: 120

    property bool isCustomState: false

    Button {

        id: myBtn1
        text: "hello"
        anchors.right: parent.right
        anchors.rightMargin: 40
        anchors.verticalCenter: parent.verticalCenter
        onClicked: {
            console.log("trying to change state to myState");
            myRectangle.isCustomState = true;
        }
    }
    Button {
        id: myBtn2
        text: "bye"
        anchors.right: parent.right
        anchors.rightMargin: 40
        anchors.verticalCenter: parent.verticalCenter
        onClicked: {
            myCppObject.coolFunction()
        }
        visible: false
    }

    Connections {
        target: myCppObject
        onCoolSignal: {
            console.log("signal triggered")
            console.log("state before signal: " + myRectangle.state);

            myRectangle.isCustomState = false;

            console.log("state after signal: " + myRectangle.state);
        }

    }

    states: [
            State {
                name: "init"
                when: !isCustomState
                PropertyChanges {
                    target: myBtn1
                    visible:true
                }
                PropertyChanges {
                    target: myBtn2
                    visible: false
                }
            },
            State {
                name: "customState"
                when: isCustomState
                PropertyChanges {
                    target: myBtn1
                    visible: false
                }
                PropertyChanges {
                    target: myBtn2
                    visible: true
                }
            }
    ]
}