Покажите пароль для диалога в Qt
Мне нужно создать диалог входа в систему, как это
файлы изображений: eyeOn.png
, eyeOff.png
Требования:
- пароль отображается только тогда, когда мы щелкаем и удерживаем значок eyeOn (даже когда мы щелкаем, удерживаем и перетаскиваем мышь в область за пределами диалогового окна, пароль все еще отображается), когда мы отпускаем мышь, пароль снова закрывается.
- пока отображается пароль, значок глаза - eyeOn. Пока пароль закрыт, значок глаза - eyeOff.
Я только что построил макет.
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);
Что я должен делать дальше? Пожалуйста, помогите мне с фрагментом кода.
2 ответа
Решение состоит в том, чтобы добавить QAction
к QLineEdit
, это создаст QToolButton
что мы можем получить из associatedWidgets()
(это будет второй виджет, так как первый виджет связан с clearButton
). Уже имея QToolButton
Вы должны использовать pressed
а также released
сигнал.
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);
}
Полный пример можно скачать по следующей ссылке.
Вместо того, чтобы пытаться использовать QAction
вернулся QLineEdit::addAction
вы могли бы использовать QWidgetAction
для этого в сочетании с подходящим фильтром событий...
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;
};
Сейчас, а не...
QAction *myAction = passwordLineEdit->addAction(QIcon(":/eyeOff.png"), QLineEdit::TrailingPosition);
Используйте...
eye_spy eye_spy(passwordLineEdit);
passwordLineEdit->addAction(&eye_spy, QLineEdit::TrailingPosition);
Кажется, чтобы обеспечить желаемое поведение.