C++ 在Qt中显示对话框的密码

C++ 在Qt中显示对话框的密码,c++,qt,qt5,qlineedit,C++,Qt,Qt5,Qlineedit,我需要创建一个这样的登录对话框 图像文件:eyeOn.png,eyeOff.png 要求: 只有当我们点击并按住eyeOn图标时,密码才会显示(即使我们点击并按住鼠标并将鼠标拖动到对话框外的区域,密码仍会显示),当我们释放鼠标时,密码再次被覆盖 显示密码时,眼睛图标为eyeOn。当密码被覆盖时,眼睛图标为eyeOff 我刚刚完成了布局 QGridLayout *mainlogin = new QGridLayout(); QLabel *usernameLabel = new QLabe

我需要创建一个这样的登录对话框

图像文件:
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);

接下来我该怎么办?请帮助我编写代码片段。

解决方案是在
QLineEdit
中添加一个
QAction
,这将创建一个
QToolButton
,我们可以从
associatedWidgets()
中获得它(这将是第二个小部件,因为第一个小部件与
clearButton
关联)。已经有了
qtool按钮
您必须使用
按下
释放
信号

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
\ifndef密码行编辑
#定义密码行编辑
#包括
#包括
#包括
类PasswordLineEdit:公共QLineEdit
{
公众:
PasswordLineEdit(QWidget*parent=nullptr);
专用插槽:
void onPressed();
释放时无效();
受保护的:
无效事件(QEvent*事件);
无效事件(QEvent*事件);
无效焦点事件(QFocusEvent*事件);
无效焦点事件(QFocusEvent*事件);
私人:
QToolButton*按钮;
};
#endif//PASSWORDLINEEDIT\u 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);
}
#包括“passwordlineedit.h”
PasswordLineEdit::PasswordLineEdit(QWidget*父项):
QLineEdit(父级)
{
setEchoMode(QLineEdit::Password);
QAction*action=addAction(QIcon(:/eyeOff),QLineEdit::TrailingPosition);
button=qobject_cast(操作->关联小部件().last());
按钮->隐藏();
按钮->设置光标(QCursor(Qt::PointingHandCursor));
连接(按钮,&QToolButton::按下,此,&PasswordLineEdit::onPressed);
连接(按钮,&QToolButton::released,this,&PasswordLineEdit::onReleased);
}
void PasswordLineEdit::onPressed(){
QToolButton*button=qobject_cast(sender());
按钮->设置图标(QIcon(:/eyeOn”);
setEchoMode(QLineEdit::Normal);
}
void PasswordLineEdit::onReleased(){
QToolButton*button=qobject_cast(sender());
按钮->设置图标(QIcon(:/eyeOff”);
setEchoMode(QLineEdit::Password);
}
无效PasswordLineEdit::enterEvent(QEvent*事件){
按钮->显示();
QLineEdit::enterEvent(事件);
}
void PasswordLineEdit::leaveEvent(QEvent*事件){
按钮->隐藏();
QLineEdit::leaveEvent(事件);
}
void PasswordLineEdit::focusInEvent(QFocusEvent*事件){
按钮->显示();
QLineEdit::focusInEvent(事件);
}
void PasswordLineEdit::focusOutEvent(QFocusEvent*事件){
按钮->隐藏();
QLineEdit::focusOutEvent(事件);
}

完整的示例可以从以下位置下载。

与其尝试使用
QLineEdit::addAction
返回的
QAction
,不如在与合适的事件筛选器结合使用时使用一个

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);

似乎提供了所需的行为。

什么是
LineEdit
class?
QLineEdit
的子类?如果是,您必须处理该子类中的鼠标按下/释放事件,并根据用户的操作设置相应的回显模式。@vahancho:对不起,这是正常的QLineEdit,我键入的错误。但是如果我能建立一个新的班级我无法想象你的想法,因此,您必须对QLineEdit进行子类
QLineEdit
,并执行我在初始评论中已经解释过的操作。@vahancho:您能用代码片段表达您的想法吗?@vahancho:您能给我一个示例,说明如何设置与用户操作相对应的回声模式吗?感谢您简单明了的解决方案。我还有一个小问题。我应该为1个要求做什么:当我们将鼠标悬停到eyeOn或eyeOff时,鼠标将变成手指,不再是光标。我自己也尝试过,也有相同的解决方案。谢谢你的支持,祝你度过愉快的一天,eyllanesc!:)我可以再问你一个问题吗?如果我需要仅当鼠标悬停在密码的LineEdit上或LineEdit处于焦点时才显示眼睛图标,我应该如何更新代码?@gnase我已经添加了该功能,还有其他问题吗?我认为你应该能够独立前进。:)非常感谢,我非常满意,也从你身上学到了很多。再次感谢你(艾伦斯克:)