views:

389

answers:

6

Is there any Qt-built-in method to warn user (with pop-up window) that CapsLock is switched on while password field is active?

I am using for passford field QLineEdit (is it good?) with setEchoMode(QLineEdit::Password).

+2  A: 

A post from Veronique Lefrere on the QT Interest mailing list has an answer, if you can wait for the user to press a key:

wait for Qt::Key_CapsLock type in a qkeyevent handler or event filter when event is QEvent::KeyPress?

Ken Bloom
I should not wait to that event, user could have CapsLock pressed earlier of invoking my application. At least I should know current state of that button!
Narek
+3  A: 

once the user presses a key, you should check if the it's upper case AND if the shift is being held. if shift is not held,and the input is uppercase,caps lock is on. also if shift is down,and the input is lowercase,caps lock is on too.

Biber
what if user never presses CapsLock during the time my application works :)?
Narek
This doesn't work on a Macintosh, because AIUI the caps lock key there just makes everything uppercase, even when Shift is pressed. (Though I admit this knowledge dates back to System 7, so it might have changed in MacOS X.)
Ken Bloom
well it should still work,if you check it on every keypress.that's just a basic idea i threw out :)
Biber
Also how to know whether shift pressed. If I could know if Shift pressed, that with the same success I will directly get the CapsLock key state.
Narek
@Narek: have a custom `bool shiftPressed = false`, and set that bool to `true` if you register a keyPressEvent for the shift key, and set it to `false` when you register a keyReleaseEvent for the shift key...
smerlin
A: 

This is really a comment to the Biber answer, but I don't have enough rep to post those :P. It's just an idea of something I read, I've never tried it :S.

It's about the way to know if shift is pressed, have you seen the Qt::KeyboardModifiers that can be detected in a Qt::KeyEvent? There's a shift modifier, It could be useful. Btw I also saw that there's a key called Qt::Key_CapsLock that can also be detected in a Key Event.

And reading the link of the bug report at the link in the comment by Narek of your question, it seems that the feature is just not available, so I think that the way to do it is to do something similar to what Biber suggest. But to avoid to wait for the user to press a key maybe you can fire/simulate a Keyboard event that puts a letter in your QLineEdit. Then check for what Biber said: If the letter is upper case and shift is pressed then... etc. And finally delete the contents of the QLineEdit. Hopefully it will happen fast enough to avoid that the user notices it :P.

It's a somewhat ugly work around but it might works. Let me know if it does!

Mkfnx
+2  A: 

Since there doesn't seem to be a cross-platform QT-native way to do this, you might want to write several platform-dependant ways with #ifdefs to select the right platform.

In that case, this QT forum article has the answer:

#ifdef Q_OS_WIN32
# include <windows.h>
#else
#  include <X11/XKBlib.h>
# undef KeyPress
# undef KeyRelease
# undef FocusIn
# undef FocusOut
// #undef those Xlib #defines that conflict with QEvent::Type enum
#endif
bool QMyClass::checkCapsLock()
{
 // platform dependent method of determining if CAPS LOCK is on
#ifdef Q_OS_WIN32 // MS Windows version
 return GetKeyState(VK_CAPITAL) == 1;
#else // X11 version (Linux/Unix/Mac OS X/etc...)
 Display * d = XOpenDisplay((char*)0);
 bool caps_state = false;
 if (d)
 {
  unsigned n;
  XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
  caps_state = (n & 0x01) == 1;
 }
 return caps_state;
#endif
}

If you put this in its own source file, so that you don't do any other QT event processing in that file, then you don't need to do the #undefs.

Ken Bloom
Thanks, it works. Nothing impossible, no? :)
Narek
@Narek, you said you were looking for something platform independent.
Ken Bloom
This should work on WINDOWS and and on... Linux, MacOS(?? on windows it works!).
Narek
@Narek: I'm not personally sure about MacOS myself. (I'm not sure whether Mac QT uses X11 or not -- maybe someone else knows the answer.)
Ken Bloom
Qt uses native OSX, not X11. Also, that X11 code is kind of horrible. You should really be using `QWidget::x11Info()` to get the `Display`.
gnud
A: 

If you're writing for KDE (and not generic Qt), then use KModifierKeyInfo::isKeyLocked().

KModifierKeyInfo info;
info.isKeyLocked(Qt::Key_CapsLock)

(warning: I haven't tested this code sample)

Ken Bloom
What the phrase "If you're writing for KDE (and not generic Qt)" means. Please in detail.
Narek
http://en.wikipedia.org/wiki/KDE It's a Linux desktop environment, which AIUI also can run on Windows or MacOS.
Ken Bloom
I dont understand how to use... Could you write a code snippet?
Narek
A: 

I have soved this problem already. I have used QToolTip http://stackoverflow.com/questions/3014879/qt-how-to-apply-a-qtooltip-on-a-qlineedit as a way to inform user about caps lock stat, and used, of course, a function that gets current state ( GetKeyState(VK_CAPITAL)). Disadvantage: this works on Windows only.

Narek