记工作中遇到的一个Qt tab order的古怪问题

问题背景:

我自己实现了一个StyledLineEdit,相比QLineEdit多了一个clear button,这个button的parent是StyledLineEdit然后我将这个控件应用到两个小的widget中,分别用来输入名字之类的,以及输入电话号码,然后把它们放在一个dialog中用来输入。


问题描述:

在非电话号码的区域输入一些字符,然后按tab,焦点可以正确跳到clear button上。在电话号码的区域输入一些字符,然后按tab,焦点不会停留在clear button上
记工作中遇到的一个Qt tab order的古怪问题_第1张图片


解决过程

说句题外话,本来我是为了解决“按了Enter会清除已输入的字符”这个问题才发现以上的问题。而这个问题是因为clear button设置了default属性为true,所以在Dialog中按enter就会自动调用它的点击事件,于是输入就被清掉了,解决方法也很简单,我在dialog的UI文件中将save button的default属性设置为了true,于是以后按Enter就会相当于直接按save。

回到本篇的问题,首先clear button是可以接受focus的,所以排除focus policy不对的可能,然后我试着用tab全部走了一遍,发现焦点根本不会经过clear button。这时候我试着Shift+Tab走了一下,发现经过combo box之后焦点走到了clear button上,也就是说它被放在了combo box的previous focus。那么为什么会出现这样的情况呢,首先是因为我在UI文件中的tab order list只有combo box,line edit和delete button(暂时被隐藏了),如图所示
tab order list
而clear button是在代码中创建的,所以Qt会根据创建的顺序把它放进tab order中。于是我又灵机一动查看了一下Qt自动生成的ui头文件的代码,发现我的line edit果然比combo box生成的早,也就是说clear button比combo box创建的要早,于是在默认的tab order中它是在combo box前面的,而我将combo box设置成了focus proxy并且让tab order从它开始,于是从它往后走就不会再focus到clear button上了。经过这一番分析,我用notepad++打开ui文件然后将combo box的代码放在了line edit之前,重新编译生成,果然!这次可以tab到clear button上了,满心欢喜的以为解决了这个奇葩的bug,测试的时候发现又有点问题。
delete button shows
当下面的delete button出现时,在经过line edit之后焦点会到delete button上,最后再到clear button。原因还是刚才说的,只有ui文件中的三个widget在tab order list中,而代码里手动生成的clear button就自动被放到了最后。自己想了很多方法解决这个问题,最后我想到,干脆让delete button也不在tab order list中吧,这样它和clear button就会根据创建的顺序被放到tab order list的后面,然后只需要让delete button晚于line edit生成,就可以保证它被放在clear button的next focus。于是我在ui文件中将delete button设置成了NoFocus,然后在构造函数中再用代码将它设置成StrongFocus,最后终于解决了这个问题

你可能感兴趣的:(Qt)