Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 绑定类型:是否可以侦听临时重写的绑定?_Qt_Qml_Qtquick2_Qt Quick - Fatal编程技术网

Qt 绑定类型:是否可以侦听临时重写的绑定?

Qt 绑定类型:是否可以侦听临时重写的绑定?,qt,qml,qtquick2,qt-quick,Qt,Qml,Qtquick2,Qt Quick,我想创建一个小部件,它的值可以绑定到自身之外的值,但也可以在内部设置该值。我希望能够支持的一个场景: 使用小部件的开发人员将小部件的值绑定到某个外部值 在运行时,小部件值通过此绑定跟踪任何外部值更改 用户与小部件交互,设置自己的值 一段时间后,外部值被更新 理想情况下,小部件值将返回到绑定到外部值 仅使用绑定时,第5点似乎不可能。下面是一个示例,“textItem”是我们想象中的小部件: import QtQuick 2.7 import QtQuick.Controls 2.0 Applic

我想创建一个小部件,它的值可以绑定到自身之外的值,但也可以在内部设置该值。我希望能够支持的一个场景:

  • 使用小部件的开发人员将小部件的值绑定到某个外部值
  • 在运行时,小部件值通过此绑定跟踪任何外部值更改
  • 用户与小部件交互,设置自己的值
  • 一段时间后,外部值被更新
  • 理想情况下,小部件值将返回到绑定到外部值
  • 仅使用绑定时,第5点似乎不可能。下面是一个示例,“textItem”是我们想象中的小部件:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
    
        property real externalValue: (Math.random()* 50).toFixed(0)
    
        Timer {
            running: true
            repeat: true
            interval: 1000
            onTriggered: {
                // Simulate externalValue changes out of our control
                externalValue = (Math.random()* 50).toFixed(0)
            }
        }
    
        Component.onCompleted: {
            // Unknown external binding set by developer using textItem widget
            textItem.text = Qt.binding(function(){return externalValue})
        }
    
        Column {
    
            Text {
                id: textItem
                text: ""
    
                property real internalValue: (Math.random()* 50).toFixed(0)
    
                Binding on text {
                    id: binding
                    value: textItem.internalValue
                    when: false
                }
            }
    
            Button {
                text: "Change Internal Value"
                onClicked: {
                    textItem.internalValue = (Math.random()* 50).toFixed(0)
                    binding.when = true
                }
            }
        }
    }
    
    
    因此textItem.text将侦听externalValue绑定,直到用户与按钮交互,然后按钮将textItem.text绑定到用户设置的内部值。假设textEdit是一个黑盒小部件,并且在其运行时绑定之前没有externalValue的概念,textEdit是否有任何方法在内部侦听重写的externalValue绑定,并在下次计时器更新externalValue时还原它(通过设置binding.when=false)


    使场景工作的一种方法是使用直接赋值代替所有绑定,但这似乎会导致一个混乱的小部件API,因为我无法阻止用户尝试使用绑定,而绑定可能会被小部件的黑盒内部分配破坏…

    您可以使用状态临时覆盖绑定,如下面的代码所示

    这里真正的问题是检测外部值何时更改,在我的解决方案中,我使用了一个
    计时器
    ,但是您的需求要求外部值再次更改。由于您正在外部绑定到属性
    文本
    ,并且还覆盖了到
    文本
    的绑定,因此您暂时从外部绑定中释放了更改信号,因此无法撤消临时绑定

    如果您可以控制小部件,我将实现一个属性,该属性应该在外部设置,并在内部将该值分配给它应该去的地方。这使您能够接收更改,例如停止
    tempbundedtimer
    (因为我仍然认为您应该有一个计时器,以防外部值无法更新时无限期地覆盖绑定)

    如果您不能控制小部件,我会为
    tempBoundedTimer

    (在任何情况下,我都不认为在小部件的每个实例中添加计时器很好)


    顺便说一句,如果
    被绑定到
    tempBoundedTimer.running
    ,我认为您的绑定对象实际上也应该工作,但我无法让它玩得很好。似乎
    Qt.binding
    具有优先级

    是的,基本问题是外部绑定的更改信号暂时丢失。这似乎是有道理的,因为QT在后台保留了绑定,所以仍然可以听到这些,但是这种功能似乎没有实现,我也没有想出任何聪明的方法来解决它。
    import QtQuick 2.7
    import QtQuick.Controls 2.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
    
        property real externalValue: (Math.random()* 50).toFixed(0)
    
        Timer {
            running: true
            repeat: true
            interval: 1000
            onTriggered: {
                // Simulate externalValue changes out of our control
                externalValue = (Math.random()* 50).toFixed(0)
            }
        }
    
    
        Component.onCompleted: {
            // Unknown external binding set by developer using textItem widget
            textItem.text = Qt.binding(function(){return externalValue})
        }
    
        Column {
    
            Text {
                id: textItem
                text: ""
    
                property real internalValue: (Math.random()* 50).toFixed(0)
    
                Timer {
                    id: tempBoundedTimer
                    repeat: false
                    interval: 2000
                }
    
                states: [
                    State {
                        when: tempBoundedTimer.running
                        PropertyChanges {
                            target: textItem
                            text: "internal:" + internalValue
                        }
                    }
                ]
            }
    
            Button {
                text: "Change Internal Value"
                onClicked: {
                    textItem.internalValue = (Math.random()* 50).toFixed(0)
                    tempBoundedTimer.start()
                }
            }
        }
    }