• QML相关bug记录


    请添加图片描述
    更多资讯、知识,微信公众号搜索:“上官宏竹”。


    浮点赋值会截断

    浮点数据直接付给QML中的整型属性,则会直接截断。比如一个属性int a,将一个40.0f的浮点型赋值给a,则a可能会为39。因为40.0f,实际表示为39.99999xxx等。此时需要向上取整或者四舍五入(Math.round(value)

    属性绑定相关

    结论

    属性绑定时,被绑定的属性的更新时机是在源属性有变化的时候,执行更新的。

    过程

    下面的代码中contentItem: STextInputtext其实是与rootItem.value绑定的(text: cusSpinBox.textFromValue(rootItem.value, cusSpinBox.locale))。而属性绑定会有一个特性,只有当源属性变化时才会触发绑定的计算。
    那么下面这段代码的被调用就值得考量了:
    它的作用是获取SpinBoxcontentItem: STextInput的输入值,改成对应的value,即从text到value的转化。
    这里有一个操作就是要判断from和to的范围,让输入的数值在这个范围内显示,当前默认最大值为2.0。
    那么这里有一个问题就是,当第一次设置超过2.0的值后,再次再设置超2.0的值后,contentItem: STextInput对应的值不再显示正确范围内的值。比如,输入5后,再输入20,第一次输入5后,contentItem: STextInput会更新到2.0,而再次输入20后,contentItem: STextInput就不会有更新,还是输入的20这个值。
    这个问题的关键就是,第一输入5后,rootItem.value的值从其他值被改为2.0,再次输入20后,rootItem.value的值还是被改为2.0,这等于没有变化。那么text: cusSpinBox.textFromValue(rootItem.value, cusSpinBox.locale)那么这段属性绑定的代码就不会再次计算,显然就不会更新contentItem: STextInput

    valueFromText: function(text, locale) {
        let tmpValue = Number.fromLocaleString(locale, text)
        console.log("valueFromText : " + text + " => " + tmpValue+" from: "+getFrom()+" to: "+getTo())
    
        if (tmpValue > getTo()) {
            tmpValue = getTo()
        }
        if (tmpValue < getFrom()) {
            tmpValue = getFrom()
        }
        let realValue = tmpValue.toFixed(decimals)
        rootItem.value = realValue
        console.log("2 realValue : " + realValue)
        return realValue
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    完整的有问题的代码如下:

    Item {
        id: rootItem
        height: 22
        implicitWidth: 80
        anchors.verticalCenter: parent.verticalCenter
    
        property int decimals: 1
        property real from: -1.0
        property real to: 2.0
        property real stepSize: 0.1
        property real value: 0.2
    
        function getFrom() {
            return Math.min(rootItem.from, rootItem.to)
        }
    
        function getTo() {
            return Math.max(rootItem.from, rootItem.to)
        }
    
        SpinBox {
            id: cusSpinBox
            anchors.fill: parent
    
            editable: true
            leftPadding: 4
            rightPadding: 4
            topPadding: 4
            bottomPadding: 4
    
            validator: DoubleValidator {
                bottom: rootItem.getFrom()
                top: rootItem.getTo()
                decimals: rootItem.decimals
            }
    
            textFromValue: function(value, locate) {
                return Number(value).toLocaleString(locale, 'f', rootItem.decimals)
            }
    
            valueFromText: function(text, locale) {
                let tmpValue = Number.fromLocaleString(locale, text)
                console.log("valueFromText : " + text + " => " + tmpValue+" from: "+getFrom()+" to: "+getTo())
    
                if (tmpValue > getTo()) {
                    tmpValue = getTo()
                }
                if (tmpValue < getFrom()) {
                    tmpValue = getFrom()
                }
                let realValue = tmpValue.toFixed(decimals)
                rootItem.value = realValue
                console.log("2 realValue : " + realValue)
                return realValue
            }
    
            contentItem: STextInput {
                id: input
                color: "blue"
                width: cusSpinBox.width - cusSpinBox.up.indicator.width - cusSpinBox.leftPadding - cusSpinBox.rightPadding
                horizontalAlignment: Qt.AlignLeft
                verticalAlignment: Qt.AlignVCenter
                validator: cusSpinBox.validator
                text: cusSpinBox.textFromValue(rootItem.value, cusSpinBox.locale)
                readOnly: !cusSpinBox.editable
                selectByMouse: true
                inputMethodHints: Qt.ImhFormattedNumbersOnly
            }
    
            up.indicator: Image {
                x: cusSpinBox.width - width - cusSpinBox.rightPadding
                y: cusSpinBox.topPadding
                width: 18
                height: (cusSpinBox.height - cusSpinBox.topPadding - cusSpinBox.bottomPadding)/2 - 2
                source: JsConfig.imgPathPrefix() + "spinbox_up.png"
            }
    
            down.indicator: Image {
                x: cusSpinBox.width - width - cusSpinBox.rightPadding
                y: cusSpinBox.height - height - cusSpinBox.bottomPadding
                width: 18
                height: (cusSpinBox.height - cusSpinBox.topPadding - cusSpinBox.bottomPadding)/2 - 2
                source: JsConfig.imgPathPrefix() + "spinbox_down.png"
            }
    
            MouseArea {
                id: downArea
                hoverEnabled: true
                width : 18
                height :parent.height / 2
                anchors.right: parent.right
                anchors.top: parent.top
                cursorShape: Qt.PointingHandCursor
                onClicked: {
                    cusSpinBox.increase()
                }
            }
    
            MouseArea {
                id : upArea
                hoverEnabled: true
                width : 18
                height : parent.height / 2
                anchors.right: parent.right
                anchors.bottom: parent.bottom
                cursorShape: Qt.PointingHandCursor
    
                onClicked: {
                    cusSpinBox.decrease()
                }
            }
    
            function increase() {
                let curRealValue = rootItem.value + rootItem.stepSize
                console.log(" 1 increase last value: "+rootItem.value+" curRealValue: "+
                            curRealValue.toFixed(decimals))
                rootItem.value = Math.min(curRealValue.toFixed(decimals), getTo())
            }
    
            function decrease() {
                let curRealValue = rootItem.value - rootItem.stepSize
                console.log(" 1 decrease last value: "+rootItem.value+" curRealValue: "+
                            curRealValue.toFixed(decimals))
                rootItem.value = Math.max(curRealValue.toFixed(decimals), getFrom())
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127

    微信公众号搜索:“上官宏竹”,关注并留言咨询,可接各类需求。


    更多资讯、知识,微信公众号搜索:“上官宏竹”。
    请添加图片描述

  • 相关阅读:
    python Kalman滤波跟踪(链接整理+理解)
    C++ 学习(七)指针、const修饰指针、指针与数组、指针与函数
    【亲测】网址引导页管理系统
    安卓Termux搭建web服务器【公网远程手机Android服务器】
    tcp三次握手的一些疑问
    如何批量修改 GitHub 代码提交作者
    Oracle之删除数据之后如何恢复的方法
    布隆过滤器原理介绍和典型应用案例
    【Redis学习笔记05】Jedis客户端(中)
    SQL连接表(内连接、左连接、右连接、交叉连接、全外连接)
  • 原文地址:https://blog.csdn.net/tanxuan231/article/details/126528832