Question

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 currently using QLineEdit (is it good?) with setEchoMode(QLineEdit::Password).

Was it helpful?

Solution 4

I have soved this problem already. I have used QToolTip 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.

OTHER TIPS

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.

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?

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.

For macs, to detect the state of the caps lock key you can do the following.

Create a .h / .mm file pair then include these files in your Qt pro file as follows:

SOURCES += myFile.h

macx: OBJECTIVE_SOURCES += myFile.mm

in myFile.h add the following...

bool IsCapsEnabled_mac();

in myFile.mm add the following (the order of the includes / imports is important)...

#include <QtCore>
#include <QtGui>
#include <QtMac>
#include "myFile.h"

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>

bool IsCapsEnabled_mac()
{
    NSUInteger flags = [NSEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
    return ( flags & NSAlphaShiftKeyMask );
}

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)

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!

Based on Ken Bloom's answer, I made a Qt project example demonstrating the key UX patterns related to this. Particularly overriding QDialog::event() to catch Caps Lock every time was critical.

https://github.com/savolai/Qt-Widgets-password-dialog-with-Caps-Lock-check

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top