在Qt中显示对话框的密码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Qt中显示对话框的密码相关的知识,希望对你有一定的参考价值。

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

enter image description here enter image description here

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

接下来我该怎么办?请帮助我使用代码段。

答案

解决方案是将QAction添加到QLineEdit,这将创建一个QToolButton,我们可以从associatedWidgets()获得(它将是第二个小部件,因为第一个小部件是与clearButton相关的小部件)。已经有QToolButton你必须使用pressedreleased信号。

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

完整的示例可以从以下link下载。

另一答案

而不是试图利用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);

似乎提供了所需的行为。

以上是关于在Qt中显示对话框的密码的主要内容,如果未能解决你的问题,请参考以下文章

执行代码时有时不显示对话框片段

在片段活动中显示自定义对话框

从片段显示对话框?

在片段中我想点击如何显示警告对话框

在tablayout viewpager中运行调整选项卡片段

我该如何做模态对话框片段(代码在我关闭之前不会执行)