Qt焦点系统
1.焦点窗口
所谓的焦点窗口,指的是当前时刻拥有键盘输入的窗口。
补充两个概念,活动窗口和前景窗口。活动窗口,指的是当前时刻与用户进行交互的窗口;前景窗口,指的是显示器最顶层窗口,前景窗口永远在其他窗口上方,不被遮挡。
不是所有的窗口都可以成为焦点窗口,只有“ 可获取焦点 ”的窗口,才有机会成为焦点窗口,Qt提供了如下接口,用于设置窗口是否是” 可获取焦点 “窗口:
void QWidget::setFocusPolicy(Qt::FocusPolicy policy);
Qt::FocusPolicy值 | 描述 |
---|---|
Qt::TabFocus | 与焦点链相关,详解见下一小节 |
Qt::ClickFocus | 单击该窗口,获得焦点 |
Qt::StrongFocus | TabFocus | ClickFocus | 0x8 |
Qt::WheelFocus | StrongFocus | 0x4 |
Qt::NoFocus | 不可获取焦点 |
setFocusPolicy()
的参数值可以是上述5个值中的任意一种,当参数值为前4个的时候,当前窗口可以获取焦点,当参数值为
Qt::Nofocus
的时候,当前窗口不可获取焦点。
2.焦点链
Qt除了把窗口对象组织成树状结构外,还把这些窗口组织成了一个双向链表结构,这个链表叫做 焦点链 。焦点链上每个节点代表一个窗口,默认情况下,窗口在焦点链上的先后位置,与用户把窗口添加到窗口树的先后顺序有关,越早添加到窗口树上的窗口,其在焦点链中的位置越靠前。
通过按
Tab
或者
Shift+Tab
,可以实现焦点在各个窗口之间循环移动。焦点移动顺序与焦点链相关,它的移动规律如下:
1.点击
Tab
键,焦点链指针向后移动,直至碰到第一个
FocusPolicy
为
TabFocus
的窗口,并设置该窗口为焦点窗口;
2.点击
Shift+Tab
,焦点链指针向前移动,直至碰到第一个
FocusPolicy
为
TabFocus
的窗口,并设置该窗口为焦点窗口;
Qt提供了下列结构,用于获取焦点链信息:
//返回此部件焦点链中的下一个部件
QWidget* QWidget::nextInFocusChain() const;
//返回此部件焦点链中的前一个部件
QWidget* QWidget::previousInFocusChain() const;
此外,我们还可以调整焦点链中节点的先后顺序
// 将焦点顺序中的部件 second 放置在部件 first 之后
static void QWidget::setTabOrder(QWidget* first, QWidget* second);
比如,若默认的焦点链顺序为 a-b-c-d,则:
setTabOrder(d,c); //改变后焦点链的顺序为 a-b-d-c
setTabOrder(b,a); //改变后焦点链的顺序为 b-a-d-c
3.切换焦点窗口
下面这些API可以用于切换焦点窗口:
// 等同于focusNextPrevChild(true)
bool QWidget::focusNextChild();
// 等同于focusNextPrevChild(false)
bool QWidget::focusPreviousChild();
// next==true:设置焦点链中下个`FocusPolicy`为`TabFocus`的窗口为焦点窗口
// next==false:设置焦点链中前一个`FocusPolicy`为`TabFocus`的窗口为焦点窗口
bool QWidget::focusNextPrevChild(bool next);
// 设置当前窗口为焦点窗口
void QWidget::setFocus(Qt::FocusReason reason);
// 取消焦点窗口
void QWidget::clearFocus();
点击
Tab
键,底层调用了
focusNextChild()
,点击
Shift+Tab
,底层调用了
focusPreviousChild()
。
setFocus(Qt::FocusReason reason)
有两个作用:设置当前窗口为焦点窗口;提供
FocusReason
信息。
4.焦点事件
与焦点事件处理相关的函数如下:
void QWidget::focusInEvent(QFocusEvent *event);
void QWidget::focusOutEvent(QFocusEvent *event);