【问题标题】:QML state not changing on C++ signalQML 状态在 C++ 信号上没有改变
【发布时间】:2018-03-26 18:29:16
【问题描述】:

我很难理解 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.onClick 更改为myRectangle.state = "init";,状态转换就会起作用!!!但我真的需要它发生在自定义 C++ 信号上!

提前感谢您的任何帮助。

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

【问题讨论】:

  • 我刚刚发现不仅连接中的信号变化没有可见的影响,而且所有其他可见的影响,如myBtn.visible = false。那么我需要以某种方式重新渲染 Rectangle 吗???
  • 我现在也有同样的问题。你解决了这个问题吗?

标签: qt signals qml qtquick2


【解决方案1】:

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

【讨论】:

  • 感谢您的回复。抱歉,myGame 是一个错字,仅存在于本示例中。为了专注于主要问题,我将我的真实代码简化为这个。
【解决方案2】:

我遇到了类似的问题,在我的情况下,我通过添加属性 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
                }
            }
    ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多