0

我正在努力理解 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”应该出现。因此,我使用所描述的状态,并且到目前为止它有效!状态发生变化,带有“再见”标签的按钮可见。

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

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

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

顺便说一句:如果我更改myBtn2.onClickmyRectangle.state = "init";状态转换工作!!!但我真的需要它发生在自定义 C++ 信号上!

感谢您提前提供任何帮助。

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

4

2 回答 2

0

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

于 2013-10-17T13:33:33.710 回答
0

我有一个类似的问题,在我的情况下,我通过添加属性 bool isCustomState 来解决它(如果你需要超过 2 个状态,你可以使用 int )并给状态一个 when 条件。然后通过该属性进行任何更改。

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
                }
            }
    ]
}
于 2018-03-26T10:29:16.140 回答