Control子类对象焦点获取
Button{
id: btn
width: 100
height: 30
focus: false
background: Rectangle{
border.color: btn.focus ? "red":"green"
border.width: 2
}
//设置当前控件如何获取焦点
/*
Qt.TabFocus
The control accepts focus by tabbing.
Qt.ClickFocus
The control accepts focus by clicking.
Qt.StrongFocus
The control accepts focus by both tabbing and clicking.
Qt.WheelFocus
The control accepts focus by tabbing, clicking, and using the mouse wheel.
Qt.NoFocus
The control does not accept focus.
*/
// focusPolicy: Qt.StrongFocus //点击或者tab
/*
Control中设置聚焦原因(只读)
focusReason:
Qt.MouseFocusReason
Qt.TabFocusReason
Qt.BacktabFocusReason
Qt.ActiveWindowFocusReason
Qt.PopupFocusReason
Qt.ShortcutFocusReason
Qt.MenuBarFocusReason
Qt.OtherFocusReason
*/
onFocusChanged: {
console.log("onFocusChanged: ", focus)
}
onFocusReasonChanged: {
console.log("onFocusReasonChanged: ", focusReason)
console.log("Qt.MouseFocusReason: ", Qt.MouseFocusReason)
console.log("Qt.TabFocusReason: ", Qt.TabFocusReason)
}
Component.onCompleted: {
console.log("focusPolicy: ", focusPolicy)
console.log("Qt.StrongFocus: ", Qt.StrongFocus)
}
}
focus=false; focusPolicy=Qt.TabFocus; 按下tab键时触发focuschanged信号
当获取焦点开启时,控件默认是获取了焦点focus的,当focus=false后仍旧可以通过点击按钮或者tab键(默认的聚焦策略)可使得按钮获取到焦点,这和我们一般认为的focus=false后这个按键就不能再获取到焦点的认识有点出入,这里引入一个activeFocus活动焦点,这个才是当前获取到的真正有效的焦点,如果当focus=false后这个控件就必须再也不能通过点击、tab等方式获取到焦点的话,就需要通过Control的属性 focusPolicy进行设置使得按钮不能获取到焦点focusPolicy: Qt.NoFocus。需要修改Control子类对象获取焦点的方式通过修改focusPolicy进而实现(这个时候控件获取focus需要按照设置的策略去获取)。
该属性决定控件如何接收到焦点
focusPolicy : enumeration
Qt.TabFocus 通过tab键
The control accepts focus by tabbing.
Qt.ClickFocus 通过鼠标点击
The control accepts focus by clicking.
Qt.StrongFocus 鼠标点击或者tab键
The control accepts focus by both tabbing and clicking.
Qt.WheelFocus 控件通过tab键、单击和使用鼠标滚轮接受焦点
The control accepts focus by tabbing, clicking, and using the mouse wheel.
Qt.NoFocus 不能获取焦点,当focus=false时一般会结合该
The control does not accept focus.
获取焦点原因(只读)
[read-only] focusReason : enumeration
Qt.MouseFocusReason 鼠标
A mouse action occurred.
Qt.TabFocusReason tab键
The Tab key was pressed.
Qt.BacktabFocusReason
A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab.
Qt.ActiveWindowFocusReason
The window system made this window either active or inactive.
Qt.PopupFocusReason
The application opened/closed a pop-up that grabbed/released the keyboard focus.
Qt.ShortcutFocusReason
The user typed a label's buddy shortcut
Qt.MenuBarFocusReason
The menu bar took focus.
Qt.OtherFocusReason
Another reason, usually application-specific.
FocusScop
上面描述了一个控件如何获取focus以及如何修改获取focus的方式。下面描述如何控制多个控件的时候如何获取focus。
同级两个控件间焦点的获取
Rectangle{
id: rect
width: 300
height: 50
Text {
id: txt1
focus: true
text: qsTr("txt1 focus: "+txt1.focus + "; activeFocus: " + txt1.activeFocus)
Component.onCompleted: {
console.log("txt1 onCompleted")
}
}
}
Rectangle{
id: rect2
width: 300
height: 50
y: 50
Text {
id: txt2
focus: true
text: qsTr("txt2 focus: "+txt2.focus + "; activeFocus: " + txt2.activeFocus)
Component.onCompleted: {
console.log("txt2 onCompleted")
}
}
}
从log中可以看出txt1后完成,focus赋给了后创建完成的txt1,这和qml的设计有关,且这个时候activeFocus也在txt1。
Rectangle{
id: rect
width: 300
height: 50
focus: true
Text {
id: txt1
focus: true
text: qsTr("txt1 focus: "+txt1.focus + "; activeFocus: " + txt1.activeFocus+ "; rect focus: " + rect.focus +"; activeFocus: " + rect.activeFocus)
Component.onCompleted: {
console.log("txt1 onCompleted")
}
}
Component.onCompleted: {
console.log("rect onCompleted")
}
}
Rectangle{
id: rect2
width: 300
height: 50
y: 50
Text {
id: txt2
focus: true
text: qsTr("txt2 focus: "+txt2.focus + "; activeFocus: " + txt2.activeFocus+ "; rect focus: " + rect2.focus +"; activeFocus: " + rect2.activeFocus)
Component.onCompleted: {
console.log("txt2 onCompleted")
}
}
Component.onCompleted: {
console.log("rect2 onCompleted")
}
}
尝试对Rectangle属性focus设置为true通过log可见无效,子控件不能通过父控件获取到焦点。
FocusScope{
id: rect
width: 300
height: 50
focus: true
Text {
id: txt1
focus: true
text: qsTr("txt1 focus: "+txt1.focus + "; activeFocus: " + txt1.activeFocus)
Component.onCompleted: {
console.log("txt1 onCompleted")
}
}
}
FocusScope{
id: rect2
width: 300
height: 50
y: 50
focus: true
Text {
id: txt2
focus: true
text: qsTr("txt2 focus: "+txt2.focus + "; activeFocus: " + txt2.activeFocus)
Component.onCompleted: {
console.log("txt2 onCompleted")
}
}
}
修改子控件的父对象为FocusScope,通过log可见FocusScope的子控件都可以获取到焦点,活动焦点(焦点真正所在的控件)的获取与FocusScope的属性focus与控件创建完成的顺序相关,当两个FocusScope 的focus都设置为false时,两个子控件都可获取到焦点focus,但都没法获取到activefocus。当txt1对应的FocusScope的focus=false,txt2对应的FocusScope的focus=true时,txt1、2都可获取到focus,但是由于txt1对应的focus=false,即便txt1是后建立完成的,这时activeFocus也不会赋给txt1,会赋给临近创建的完成的txt2。FocusScope 的属性focus=true表示这个子控件真的能获取到这个活动焦点。
强制改变activeFocus
forceActiveFocus(Qt::FocusReason reason)
forceActiveFocus()
通过修改Item元素的方法forceActiveFocus() 使得控件强制获取到activeFocus。 activeFocus是只读属性,不可修改。
FocusScope{
id: rect2
width: 300
height: 50
y: 50
focus: true
Text {
id: txt2
focus: true
text: qsTr("txt2 focus: "+txt2.focus + "; activeFocus: " + txt2.activeFocus)
Component.onCompleted: {
console.log("txt2 onCompleted")
}
onFocusChanged: {
console.log("txt2 focus: "+activeFocus)
}
}
MouseArea{
anchors.fill: parent
onClicked: {
// txt2.focus = true
txt2.forceActiveFocus() //强制获取焦点
}
}
}
当使用forceActiveFocus() 强制获取activeFocus时,设置FocusScope 属性focus= false 和Text属性focus=false是无效操作,控件仍旧能够获取到焦点和活动焦点。
从上面也可看出,多个控件可以同时获取到focus,所以判断focus是否为true来确认是否获取到焦点是不准确的,当判断activeFocus(这个操作有点像windows桌面选中多个图标是多个图标都获取到了focus,仅仅是感觉没细究)。
特殊指定控件状态切换
// FocusScope
Rectangle
{
id: rect
width: 300
height: 100
focus: true
Button {
id: btn1
width: 100
height: 50
focus: true
background: Rectangle{
// border.color: btn1.focus ? "red":"green"
border.color: btn1.activeFocus ? "red":"green" //activeFocus体现了唯一性
border.width: 2
}
}
}
// FocusScope
Rectangle
{
id: rect2
width: 300
height: 100
y: 150
focus: true
Button {
id: btn2
width: 100
height: 50
focus: true
background: Rectangle{
// border.color: btn2.focus ? "red":"green"
border.color: btn2.activeFocus ? "red":"green"
border.width: 2
}
}
}
这里使用activeFocus在同级中只能一个控件唯一的获取到特性,这里同级的Rectangle 能区别activeFocus不是FocusScope实现的。可通过 鼠标点击和tab键进行选中控件的切换,这时默认focusPolicy决定的,当需要设置只能点击进行切换时,如下设置:
// FocusScope
Rectangle
{
id: rect
width: 300
height: 50
focus: true
Button {
id: btn1
width: 100
height: 50
focus: true
focusPolicy: Qt.NoFocus
background: Rectangle{
// border.color: btn1.focus ? "red":"green"
border.color: btn1.activeFocus ? "red":"green" //activeFocus体现了唯一性
border.width: 2
}
onFocusChanged: {
console.log("btn1 onFocusChanged: ", focus)
}
onActiveFocusChanged: {
console.log("btn1 onActiveFocusChanged: ", activeFocus, "; focus: ", focus)
}
onClicked: {
btn1.forceActiveFocus()
}
}
}
// FocusScope
Rectangle
{
id: rect2
width: 300
height: 50
y: 80
focus: true
Button {
id: btn2
width: 100
height: 50
focus: true
focusPolicy: Qt.NoFocus
background: Rectangle{
// border.color: btn2.focus ? "red":"green"
border.color: btn2.activeFocus ? "red":"green"
border.width: 2
}
onFocusChanged: {
console.log("btn2 onFocusChanged: ", focus)
}
onActiveFocusChanged: {
console.log("btn2 onActiveFocusChanged: ", activeFocus, "; focus: ", focus)
}
onClicked: {
btn2.forceActiveFocus()
}
}
}
通过如下修改focusPolicy的也可做到这个效果:
// FocusScope
Rectangle
{
id: rect
width: 300
height: 50
focus: true
Button {
id: btn1
width: 100
height: 50
focus: true
focusPolicy: Qt.ClickFocus
background: Rectangle{
// border.color: btn1.focus ? "red":"green"
border.color: btn1.activeFocus ? "red":"green" //activeFocus体现了唯一性
border.width: 2
}
onFocusChanged: {
console.log("btn1 onFocusChanged: ", focus)
}
onActiveFocusChanged: {
console.log("btn1 onActiveFocusChanged: ", activeFocus, "; focus: ", focus)
}
// onClicked: {
// btn1.forceActiveFocus()
// }
}
}
// FocusScope
Rectangle
{
id: rect2
width: 300
height: 50
y: 80
focus: true
Button {
id: btn2
width: 100
height: 50
focus: true
focusPolicy: Qt.ClickFocus
background: Rectangle{
// border.color: btn2.focus ? "red":"green"
border.color: btn2.activeFocus ? "red":"green"
border.width: 2
}
onFocusChanged: {
console.log("btn2 onFocusChanged: ", focus)
}
onActiveFocusChanged: {
console.log("btn2 onActiveFocusChanged: ", activeFocus, "; focus: ", focus)
}
// onClicked: {
// btn2.forceActiveFocus()
// }
}
}
在上的基础上修改focusPolicy: Qt.TabFocus可实现通过tab键切换的效果。