FocusScope and activeFocus since Qt 4.8.2



  • Hi, everyone.

    We have a problem that appeared with the correction in QDeclarativeItem::hasActiveFocus() in 4.8.2 release.

    The documentation http://qt-project.org/doc/qt-4.8/qdeclarativefocus.html states that: “Both the focus scope and the sub-focused item will have activeFocus property set.”

    Our code relies on this, and it doesn't seem to be true anymore. Did we miss something?

    Here is an example (two files) to illustrate the behavior. The enclosing box doesn't show 'activeFocus=true' at any time in 4.8.2 and 4.8.3, as it did before.

    (Windows 7)

    @
    // test.qml, to be loaded with qmlviewer
    import QtQuick 1.0

    Item {

    width: 800
    height: 600
    focus: true
    
    Keys.onUpPressed: container1_focusScope.focus = true
    Keys.onDownPressed: container2_focusScope.focus = true
    
    ListView_FocusScope {
        id: container1_focusScope
    
        anchors.top: parent.top
        anchors.topMargin: 50
    }
    
    
    ListView_FocusScope {
        id: container2_focusScope
    
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 50
    }
    

    }
    @

    @
    // ListView_FocusScope.qml
    import QtQuick 1.0

    ListView {

    width: 580
    height: 200
    anchors.horizontalCenter: parent.horizontalCenter
    spacing: 10
    orientation: ListView.Horizontal
    model: 3
    
    delegate: Rectangle {
    
        width: 180
        height: 80
        anchors.verticalCenter: parent.verticalCenter
        color: activeFocus ? "red" : "black"
    
        // text to display "focus" value
        Text {
            text: "focus="+parent.focus
            font.pixelSize: 16
            font.bold: true
            color: "white"
            font.underline: parent.focus ? true : false
        }
    
        // text to display "activeFocus" value
        Text {
            text: "activeFocus="+parent.activeFocus
            anchors.top: parent.top
            anchors.topMargin: 20
            font.pixelSize: 16
            font.bold: true
            color: "white"
            font.underline: parent.activeFocus ? true : false
        }
    }
    
    // background
    Rectangle {
        z: -1
        anchors.fill: parent
        color: "grey"
    }
    
    // text to display "focus" value
    Text {
        text: "focus="+parent.focus
        font.pixelSize: 16
        font.bold: true
        color: "white"
        font.underline: parent.focus ? true : false
    }
    
    // text to display "activeFocus" value
    Text {
        text: "activeFocus="+parent.activeFocus
        anchors.top: parent.top
        anchors.topMargin: 20
        font.pixelSize: 16
        font.bold: true
        color: "white"
        font.underline: parent.activeFocus ? true : false
    }
    

    }
    @



  • I had similar issues recently and the workaround was to use Item::forceActiveFocus() to set focus on the component.



  • Same issue here on 4.8.2 and 4.8.3 on Linux and Mac.

    This seems to be a bug in Qt since The "Key Interaction: Focus Example" demo code that comes with Qt and demonstrates how FocusScope works no longer behave correctly since 4.8.2: once the "context" menu on the left is opened, it does not disappear after a right click (its visibility depends on the activeFocus property of mainView FocusScope which does not switch to "true" when one of its children gets focus)

    It seems that the active focus is correctly proxied to the children but the intermediate focus scope do not get active focus set.



  • I tried to use forceActiveFocus() in various places in our code but to no avail. Trollixx, could you share more about your workaround? I am really interested in making this thing work.



  • There is indeed a serious bug in QML regarding scopes
    The following example shows this. It uses a similar principle as the focus example demo. Left click on the 'Change focus' will change the focus to the right rectangle. Pressing 'right mouse button' in the 'change focus area' will dump out all the activeFocus properties. Each time it seems that the activeFocus properties are correct. When changing the focus to the right rectangle it becomes green and the state change makes both rectangles moving to the right. Pressing 'left arrow' key changes the focus back to the left rectangle. But the state change is not performed, despite the 'when' property should be false ! (check this with 'right mouse button')
    @import QtQuick 1.1

    Rectangle {
    width: 600
    height: 480
    id: main

    function showFocusStatus() {
        console.log("--------------------")
        console.log("scope1 active focus", scope1.activeFocus)
        console.log("scope2 active focus", scope2.activeFocus)
        console.log("rect1 active focus", rect1.activeFocus)
        console.log("rect2 active focus", rect2.activeFocus)
        console.log("State is", main.state)
        console.log("--------------------")
    }
    
    FocusScope {
        id: scope1
        x: 10
        y: 10
        width: rect1.width
        height: rect1.height
        focus: true
        onActiveFocusChanged: {
            console.log("Active focus for scope1 changed to " + focus)
        }
    
        Rectangle {
            id: rect1
            width: 200
            height: 200
            focus: true
            color: {
                if (activeFocus)
                    "green"
                else
                    "red"
            }
        }
    }
    
    FocusScope {
        id: scope2
        focus: false
        width: rect2.width
        height: rect2.height
        anchors.top: scope1.top
        anchors.left: scope1.right
        anchors.leftMargin: 20
        onActiveFocusChanged: {
            console.log("Active focus for scope2 changed to " + focus)
        }
        Rectangle {
            id: rect2
            width: 200
            height: 200
            focus: true
            color: {
                if (activeFocus)
                    "green"
                else
                    "red"
            }
            Keys.onLeftPressed: {
                //scope1.focus = true
                scope1.forceActiveFocus()
            }
        }
    }
    
    Rectangle {
        property int focusRect: 1
        id: button
        width: parent.width
        height: 30
        color: "steelblue"
        anchors.bottom: parent.bottom
        Text {
            anchors.centerIn: parent
            text: "Change focus"
            color: "white"
            font.pointSize: 20
        }
    
        MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            onClicked: {
                if (mouse.button == Qt.LeftButton) {
                    //scope2.focus = true
                    scope2.forceActiveFocus()
                    console.log("Changing focus to rect2")
                } else {
                    main.showFocusStatus()
                }
            }
        }
    }
    
    states: [
        State {
            name: "rightActive"
            when: !scope1.activeFocus
            StateChangeScript{script: console.log("Entered right active state")}
            PropertyChanges {
                target: scope1
                x: 60
            }
        }
    ]
    
    onStateChanged: {
        console.log("State changed to <" + state + ">")
    }
    

    }
    @
    To be continued...

    Wim.



  • I can confirm that the previous QML program works correct with Qt4.7.4. All the strange issues just disappear when using the qmlviewer from Qt 4.7.4. I really hope that the Qt guys put some more effort in not breaking things in newer releases that worked in older releases. Has this bug been already reported ? For me this thing must be solved ASAP as is seems to be a fundamental part of QML.

    Wim.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.