Reputation: 638
I need to create a login dialog like this
image files: eyeOn.png
, eyeOff.png
Requirements:
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.
Upvotes: 3
Views: 3445
Reputation: 243945
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.
Upvotes: 5
Reputation: 12879
Rather than trying to make use of the QAction
returned by QLineEdit::addAction
you could probably use a QWidgetAction
for this when combined with a suitable event filter...
class eye_spy: public QWidgetAction {
using super = QWidgetAction;
public:
explicit eye_spy (QLineEdit *control, QWidget *parent = nullptr)
: super(parent)
, m_control(control)
, m_on(":/eyeOn")
, m_off(":/eyeOff")
, m_pixmap_size(50, 50)
{
m_label.setScaledContents(true);
m_control->setEchoMode(QLineEdit::Password);
m_label.setPixmap(m_off.pixmap(m_pixmap_size));
m_label.installEventFilter(this);
setDefaultWidget(&m_label);
}
protected:
virtual bool eventFilter (QObject *obj, QEvent *event) override
{
if (event->type() == QEvent::MouseButtonPress) {
m_control->setEchoMode(QLineEdit::Normal);
m_label.setPixmap(m_on.pixmap(m_pixmap_size));
} else if (event->type() == QEvent::MouseButtonRelease) {
m_control->setEchoMode(QLineEdit::Password);
m_label.setPixmap(m_off.pixmap(m_pixmap_size));
}
return(super::eventFilter(obj, event));
}
private:
QLineEdit *m_control;
QLabel m_label;
QIcon m_on;
QIcon m_off;
QSize m_pixmap_size;
};
Now, rather than...
QAction *myAction = passwordLineEdit->addAction(QIcon(":/eyeOff.png"), QLineEdit::TrailingPosition);
Use...
eye_spy eye_spy(passwordLineEdit);
passwordLineEdit->addAction(&eye_spy, QLineEdit::TrailingPosition);
Seems to provide the desired behaviour.
Upvotes: 3