PDA

View Full Version : Focus bug in windows



zerobala
7th December 2007, 14:03
Hello,

I'm desperate with tab order.

Qt Designer's tab order editing won't function for custom widgets (they show up as a single widget). I got nowhere using QWidget::setTabOrder. So I decided to re-implement focusNextPrevChild (build a QList of widget*, run through the list and do setFocus()) in a class and call it from my windows.

It works fine on Linux. The problem is: windows XP just won't paint the focus, but it's there (e.g. if I hit spacebar the button will click). Tried a lot of work-arounds and I'm very frustrated.
The funny thing is, I created an empty form with some buttons and tried setFocus() with no success. But after I hit tab and Qt changes and paint focus, setFocus() will paint correctly.

What's the method Qt uses for giving focus to a widget?

jpn
7th December 2007, 14:05
Hi. Check the focusPolicy (http://doc.trolltech.com/latest/qwidget.html#focusPolicy-prop) of your custom widget.

zerobala
7th December 2007, 14:10
Hi. Check the focusPolicy (http://doc.trolltech.com/latest/qwidget.html#focusPolicy-prop) of your custom widget.

Already did.
Even set focusPolicy on each of the 3 buttons of my custom widget on the constructor, it still won't work.

jpn
7th December 2007, 16:08
Qt Designer's tab order editing won't function for custom widgets (they show up as a single widget).
Are we talking about promoted custom widgets or did you write a designer plugin for the custom widget?


The funny thing is, I created an empty form with some buttons and tried setFocus() with no success. But after I hit tab and Qt changes and paint focus, setFocus() will paint correctly.
Does the problem exists in Designer only?

zerobala
9th December 2007, 18:44
Are we talking about promoted custom widgets or did you write a designer plugin for the custom widget?


Does the problem exists in Designer only?

I wrote a designer plugin.

No, the problem shows when I try to use setFocus() in my application (only in windows). But it's not exclusive to custom widgets.
The fact is, an empty form with two buttons, the click slot of the first connected to setFocus() on the second and this won't paint the focus in Windows XP. But if I tab through the widgets and just one button-like focus (the "focus frame" like in the checkbox) is painted, then setFocus() will work correctly.

Sorry if my english is bad, I'm brazilian :D

jpn
9th December 2007, 19:01
The fact is, an empty form with two buttons, the click slot of the first connected to setFocus() on the second and this won't paint the focus in Windows XP. But if I tab through the widgets and just one button-like focus (the "focus frame" like in the checkbox) is painted, then setFocus() will work correctly.
Could you attach such example, please? I'd like to take a look. :)

zerobala
10th December 2007, 11:37
Could you attach such example, please? I'd like to take a look. :)

Button "apply" should paint focus on "cancel" and vice-versa, but they'll work properly only after focus is painted on one of the buttons via tab.

jpn
10th December 2007, 12:20
Looks like windows style implementation actually has a check that the button focus is only drawn when focus has been changed with the keyboard (tab, backtab, or shortcut), in other words, when attribute Qt::WA_KeyboardFocusChange (http://doc.trolltech.com/latest/qt.html#WidgetAttribute-enum) is set. This can't even be worked around by passing appropriate focus reason (which I suspected to solve the problem at first sight)

btCancel->setFocus(Qt::TabFocusReason);
One would have to set the attribute to the top level window by hand. I'm afraid I cannot recommend such workaround because it could break something else. Here it goes anyways :)


window()->setAttribute(Qt::WA_KeyboardFocusChange);
btCancel->setFocus();

You can always send a bug report to Trolltech if you feel it should behave differently.

Edit: Oh, and there is another way to work it around I forgot to mention. A custom style which returns true for QStyle::styleHint(QStyle::SH_UnderlineShortcut).

zerobala
10th December 2007, 12:32
Looks like windows style implementation actually has a check that the button focus is only drawn when focus has been changed with the keyboard (tab, backtab, or shortcut), in other words, when attribute Qt::WA_KeyboardFocusChange (http://doc.trolltech.com/latest/qt.html#WidgetAttribute-enum) is set. This can't even be worked around by passing appropriate focus reason (which I suspected to solve the problem at first sight)

btCancel->setFocus(Qt::TabFocusReason);
One would have to set the attribute to the top level window by hand. I'm afraid I cannot recommend such workaround because it could break something else. Here it goes anyways :)


window()->setAttribute(Qt::WA_KeyboardFocusChange);
btCancel->setFocus();

You can always send a bug report to Trolltech if you feel it should behave differently.

Edit: Oh, and there is another way to work it around I forgot to mention. A custom style which returns true for QStyle::styleHint(QStyle::SH_UnderlineShortcut).

Thank you for your help!

zerobala
11th December 2007, 16:40
Oops, it's not working for toolbuttons on default XP theme, same problem. Any suggestion?

jpn
21st December 2007, 20:45
Oops, it's not working for toolbuttons on default XP theme, same problem. Any suggestion?
I guess this is specific to WinXP. It seems that QToolButton does not draw any focus rect at all on WinXP. Try your app with old windows-style ("myapp.exe -style windows") and it will.

PS. Sorry for late response. I was in hurry and totally forgot this..