Qml失焦问题

Qml常见诡异失焦情况一般为明明设置了某一控件的焦点, 实际却是不生效。这到底时什么情况呢?用例子来分析这种情况。

1.常见失焦情况

  • 被其他控件抢夺;
  • 误以为设置成功。

2.关于控件被抢夺的情况

2.1 先看下列例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Dialog {
id: dialog
width: 100; height: 100
onHidden: {
dialog.forceReset() // restore focus to 'yes' button
}
}

Rectangle {
width: 100; height: 200
color: activeFocus ? "red" : "lightblue"

MouseArea {
anchors.fill: parent
onClicked: {
parent.forceActiveFocus()
dialog.hide();
}
}
}

2.2 为什么这样会导致Rectangle失焦呢?

  • 当按钮按下,Dialog被关闭并恢复其原来的焦点状态;
  • 因为dialog.hide()调用后dialog重新获得了焦点。

2.3 应该这种情况应该怎么做?

  • 确保设置焦点后的逻辑不能再有其他设置焦点的行为;
  • 将焦点设置放到最后执行;
  • 可以使用定时器延时执行,确保其他焦点被还原的同时自己却又是最后获得焦点。

3.一般控件获得焦点的情况

3.1 直接设置获得焦点

  • 当onClicked被触发调用Rectangle的forceActiveFocus,以至于获得焦点;
  • 也可以直接设置focus的值来获得焦点。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Rectangle {
    width: 100; height: 200
    focus: true
    color: activeFocus ? "red" : "lightblue"

    MouseArea {
    anchors.fill: parent
    onClicked: parent.forceActiveFocus()
    }
    }

3.2 间接获得焦点

  • 当FocusScope获得了焦点,由于rect事先设置了focus:true间接地获得焦点了。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    FocusScope {
    id: scope
    width: 100; height: 200
    focus: false

    Rectangle {
    id: rect
    anchors.fill: parent
    focus: true
    color: activeFocus ? "red" : "lightblue"
    }
    }