【问题标题】:Binding Checkbox 'checked' property with a C++ object Q_PROPERTY将 Checkbox 'checked' 属性与 C++ 对象 Q_PROPERTY 绑定
【发布时间】:2014-05-25 21:45:01
【问题描述】:

我正在学习 QtQuick,我正在研究 C++ 类和 QML 属性之间的数据绑定。

在我的 C++ 对象模型中,我有两个属性:

Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool status READ getStatus WRITE setStatus NOTIFY statusChanged)

在我的 .qml 文件中:

TextEdit {
    placeholderText: "Enter your name"
    text: user.name
}

Checkbox {
    checked: user.status
}

当我在 C++ 代码中使用 setName 更改用户名时,它会自动反映在视图中。 当我选中/取消选中复选框时,或者当我从 C++ 代码中调用 setStatus() 时,什么都没有发生。似乎复选框的属性checkedTextEdit 组件的行为不同。

我不想以声明方式绑定我的属性。 Qt Quick 不支持属性绑定吗?

感谢您的帮助。

【问题讨论】:

  • 您在checkeduser.status 之间设置绑定的方式,这意味着当user.status 更改时,该复选框将被(取消)选中。如果用户点击复选框,绑定就会被移除。
  • 反之,它应该工作:当你调用setStatus时,它应该改变QML中的user.status属性并确实触发复选框只要你之前没有点击过。这仅在您在setStatus 内发出statusChanged 信号时才有效。
  • 感谢您的评论。我确实想要您在第一条评论中描述的行为(如果值更改,复选框应该更改)但我也希望用户能够选中/取消选中它。如果我理解,触发复选框会破坏绑定。它是 QtQuick 行为,还是 Checkbox 特定的?如果我创建自己的复选框/开关组件,我可以禁用此行为吗?
  • 我仔细检查了发出的信号,在setStatus 方法中进行了调试,但即使是“用户单击复选框”的情况也不起作用。明天我将使用另一个属性名称进行测试(也许“启用”用于 QML 中的内部内容),并将使用最少的代码重试。感谢您的帮助。
  • 好吧,如果您希望在用户单击复选框时更改您的属性,您需要执行其他操作。您想要的本质上是一个 双向 绑定,它在 QtQuick 中不(直接)支持,换句话说,您需要一些 C++ 或 QML (JavaScript) 中的代码

标签: c++ qt data-binding checkbox qt-quick


【解决方案1】:

正如 leemes 所指出的,用户单击复选框会破坏您创建的绑定。因此,不要创建绑定,而是直接连接到更改信号以处理“获取”情况。使用“onClicked”来处理“set”的情况。此解决方案还要求您在 Component.onCompleted() 中进行初始化。比如……

CheckBox {
    id: myCheck
    onClicked: user.status = checked
    Component.onCompleted: checked = user.status
    Connections {
        target: user
        onStatusChanged: myCheck.checked = user.status
    }
}

【讨论】:

  • 迈克你帮了我很多,尽管我花了一点时间才理解绑定中断的原因。可能是因为内部复选框的实现有onCheckedChanged: checked = !checked之类的东西,不是吗?到目前为止,我认为two way bindings 适用于每个 QML 组件,但事实并非如此;现在我想知道:我如何理解何时可以使用双向绑定以及何时必须依赖连接?
【解决方案2】:

解决此问题的一种方法是通过以下方式恢复onClicked 中的绑定(通过用户单击复选框删除):

CheckBox {
    checked: user.status
    onClicked: {
        user.status = checked;
        checked = Qt.binding(function () { // restore the binding
            return user.status;
        });
    }
}

如果您在调用 Component.onCompleted 时无法访问您的模型,这可以避免出现问题。

【讨论】:

    【解决方案3】:

    我发现让复选框只在点击时发出信号而不改变其状态更自然:

    // MyCheckBox.qml 
    CheckBox {
       id: control
    
       property bool changeOnClick: true // or just emit clicked()
    
        MouseArea {
            anchors.fill: parent
            enabled: !control.changeOnClick
            onClicked: control.clicked();
        }
    }
    

    然后你可以绑定一次,点击请求更改源:

    MyCheckBox {
        changeOnClick: false
        checked: user.state
        onClicked: {
            user.state = !user.state;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 2012-11-15
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 2015-07-24
      相关资源
      最近更新 更多