Qt控件焦点切换

admin 2022年10月2日07:34:40评论66 views字数 3263阅读10分52秒阅读模式

人们日常切换控件,例如QQ登陆的账号和密码输入框就可以通过Tab键切换焦点。 
Qt控件焦点切换 
图1 qq切换焦点 
Qt中QWidget提供了一个静态方式实现该效果 
其中也包含介绍使用


[static] void QWidget::setTabOrder(QWidget *first, QWidget *second)Puts the second widget after the first widget in the focus order.Note that since the tab order of the second widget is changed, you should order a chain like this:
setTabOrder(a, b); // a to b setTabOrder(b, c); // a to b to c setTabOrder(c, d); // a to b to c to d
not like this:
// WRONG setTabOrder(c, d); // c to d setTabOrder(a, b); // a to b AND c to d setTabOrder(b, c); // a to b to c, but not c to d
If first or second has a focus proxy, setTabOrder() correctly substitutes the proxy.

实现效果如下 
Qt控件焦点切换 
图2 Tab切换焦点 
主要部分源码

 QPushButton *p = new QPushButton("按钮");    QLineEdit *l = new QLineEdit("输入框");    QCheckBox *c =  new QCheckBox("复选框");    QComboBox *b = new QComboBox;    setTabOrder(p, l);    setTabOrder(l, c);    setTabOrder(c, b);

当然也可以让控件屏蔽焦点的使用,或者接受响应其他类型的焦点方式 
主要使用

void setFocusPolicy(Qt::FocusPolicy policy)

其中Qt::FocusPolicy 这个枚举类型定义了一个控件可以用来获取键盘焦点的各种策略。

Constant Value Description
Qt::TabFocus 0x1 the widget accepts focus by tabbing.
Qt::ClickFocus 0x2 the widget accepts focus by clicking.
Qt::StrongFocus TabFocus | ClickFocus | 0x8 he widget accepts focus by both tabbing and clicking. On macOS this will also be indicate that the widget accepts tab focus when in ‘Text/List focus mode’.
Qt::WheelFocus StrongFocus | 0x4 like Qt::StrongFocus plus the widget accepts focus by using the mouse wheel.
Qt::NoFocus 0 the widget does not accept focus.

例如设置 
QCheckBox为NoFouse

c->setFocusPolicy(Qt::NoFocus);

效果如下 
Qt控件焦点切换 
图3 复选框设置NoFocuse 
函数

[slot] void QWidget::setFocus() //可通过信号槽方式设置This is an overloaded function. Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its parents is the active window.

可直接设置焦点

接下来可以看一下Qt是怎么实现焦点切换的,查看qwidget.cpp源码


void QWidget::setTabOrder(QWidget* first, QWidget *second){ //如果这两个控件都设置为没有焦点则不进行焦点设置,如图3中所示 if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus) return;
/****************************************************************** QWidget *QWidget::window() const { QWidget *w = const_cast(this); QWidget *p = w->parentWidget(); while (!w->isWindow() && p) { w = p; p = p->parentWidget(); } return w; } ******************************************************************/ //查看当前控件“祖先”(ancestor widget)窗口,见上面代码 if (Q_UNLIKELY(first->window() != second->window())) { qWarning("QWidget::setTabOrder: 'first' and 'second' must be in the same window"); return; }
//找到first或其子类中焦点的控件(不是很懂) QWidget *fp = first->focusProxy(); if (fp) { QList l = first->findChildren(); for (int i = l.size()-1; i >= 0; --i) { QWidget * next = l.at(i); if (next->window() == fp->window()) { fp = next; if (fp->focusPolicy() != Qt::NoFocus) break; } } first = fp; }
if (fp == second) return;
if (QWidget *sp = second->focusProxy()) second = sp;
//双向链表存储焦点触发控件顺序// QWidget *fp = first->d_func()->focus_prev; QWidget *fn = first->d_func()->focus_next;
if (fn == second || first == second) return;
QWidget *sp = second->d_func()->focus_prev; QWidget *sn = second->d_func()->focus_next;
fn->d_func()->focus_prev = second; first->d_func()->focus_next = second;
second->d_func()->focus_next = fn; second->d_func()->focus_prev = first;
sp->d_func()->focus_next = sn; sn->d_func()->focus_prev = sp;
//查错 Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first); Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first);
Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second); Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second);}

http://blog.csdn.net/gx864102252/article/details/72731992

Qt控件焦点切换


原文始发于微信公众号(汇编语言):Qt控件焦点切换

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年10月2日07:34:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Qt控件焦点切换http://cn-sec.com/archives/1330181.html

发表评论

匿名网友 填写信息