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.0Item {
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.0ListView {
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 }
}
@ -
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.
-
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.1Rectangle {
width: 600
height: 480
id: mainfunction 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.