Search code examples
c++qtqt5qlineedit

Reveal password for dialog in Qt


I need to create a login dialog like this

enter image description here enter image description here

image files: eyeOn.png, eyeOff.png

Requirements:

  • password is shown only when we CLICK AND HOLD the eyeOn icon (even when we click and hold and drag the mouse to area outside of the dialog, the password is still shown), when we release the mouse, password is covered again.
  • while password is shown, the eye icon is eyeOn. While password is covered, the eye icon is eyeOff.

I have just built the layout.

QGridLayout *mainlogin = new QGridLayout();

QLabel *usernameLabel = new QLabel;
usernameLabel->setWordWrap(true);
usernameLabel->setText("Username");
mainlogin->addWidget(usernameLabel, 0, 0);

QComboBox *usernameLineEdit = new QComboBox;
usernameLineEdit->setEditable(true);
usernameLabel->setBuddy(usernameLineEdit);
mainlogin->addWidget(usernameLineEdit, 0, 1);

QLabel *capslockShow = new QLabel;
capslockShow->setWordWrap(true);
capslockShow->setText(" ");
mainlogin->addWidget(capslockShow, 1, 1);

QLabel *passwordLabel = new QLabel;
passwordLabel->setWordWrap(true);
passwordLabel->setText("Password");
mainlogin->addWidget(passwordLabel, 2, 0);
QLineEdit *passwordLineEdit = new QLineEdit;
passwordLineEdit->setEchoMode(QLineEdit::Password);
QAction *myAction = passwordLineEdit->addAction(QIcon(":/eyeOff.png"), QLineEdit::TrailingPosition);
passwordLabel->setBuddy(passwordLineEdit);
mainlogin->addWidget(passwordLineEdit, 2, 1);

What should I do next? Pls help me with code snippet.


Solution

  • The solution is to add a QAction to the QLineEdit, this will create a QToolButton that we can obtain from the associatedWidgets() (it will be the second widget since the first one is the one associated with clearButton). Already having the QToolButton you must use the pressed and released signal.

    passwordlineedit.h

    #ifndef PASSWORDLINEEDIT_H
    #define PASSWORDLINEEDIT_H
    
    #include <QAction>
    #include <QLineEdit>
    #include <QToolButton>
    
    class PasswordLineEdit: public QLineEdit
    {
    public:
        PasswordLineEdit(QWidget *parent=nullptr);
    private slots:
        void onPressed();
        void onReleased();
    protected:
        void enterEvent(QEvent *event);
        void leaveEvent(QEvent *event);
        void focusInEvent(QFocusEvent *event);
        void focusOutEvent(QFocusEvent *event);
    private:
        QToolButton *button;
    };
    
    #endif // PASSWORDLINEEDIT_H
    

    passwordlineedit.cpp

    #include "passwordlineedit.h"
    
    PasswordLineEdit::PasswordLineEdit(QWidget *parent):
        QLineEdit(parent)
    {
        setEchoMode(QLineEdit::Password);
        QAction *action = addAction(QIcon(":/eyeOff"), QLineEdit::TrailingPosition);
        button = qobject_cast<QToolButton *>(action->associatedWidgets().last());
        button->hide();
        button->setCursor(QCursor(Qt::PointingHandCursor));
        connect(button, &QToolButton::pressed, this, &PasswordLineEdit::onPressed);
        connect(button, &QToolButton::released, this, &PasswordLineEdit::onReleased);
    }
    
    void PasswordLineEdit::onPressed(){
        QToolButton *button = qobject_cast<QToolButton *>(sender());
        button->setIcon(QIcon(":/eyeOn"));
        setEchoMode(QLineEdit::Normal);
    }
    
    void PasswordLineEdit::onReleased(){
        QToolButton *button = qobject_cast<QToolButton *>(sender());
        button->setIcon(QIcon(":/eyeOff"));
        setEchoMode(QLineEdit::Password);
    }
    
    void PasswordLineEdit::enterEvent(QEvent *event){
        button->show();
        QLineEdit::enterEvent(event);
    }
    
    void PasswordLineEdit::leaveEvent(QEvent *event){
        button->hide();
        QLineEdit::leaveEvent(event);
    }
    
    void PasswordLineEdit::focusInEvent(QFocusEvent *event){
        button->show();
        QLineEdit::focusInEvent(event);
    }
    
    void PasswordLineEdit::focusOutEvent(QFocusEvent *event){
        button->hide();
        QLineEdit::focusOutEvent(event);
    }
    

    The complete example can be downloaded from the following link.