仅显示 QLineEdit 中的最后一个字符几秒钟

问题描述 投票:0回答:1

QLineEdit 提供 4 种 EchoMode 状态

输入密码时,QLineEdit::Password 很合适,因为它显示一个圆圈(或类似的东西)而不是输入的字符。

我想要做的是隐藏所有字符,就像 QLineEdit::Password 一样,但最后输入的字符在被圆圈替换之前会显示几秒钟。这允许用户检查他们是否正确使用了密码。

但是,在一段时间后我无法绘制圆圈符号而不是可见字符。

我尝试使用连接到 update() 插槽的 QTimer,但到目前为止没有成功。

lineeditvanishingcharacters.cpp

#include "lineeditvanishingcharacters.h"

#include <QTextLayout>
#include <QPainter>

LineEditVanishingCharacters::LineEditVanishingCharacters(QWidget *parent)
    : QLineEdit(parent)
    , m_is_new_character(false)
{
    setEchoMode(QLineEdit::Password);
}

void LineEditVanishingCharacters::paintEvent(QPaintEvent *event)
{
    if(text().isEmpty()) {
        QLineEdit::paintEvent(event);
        return;
    }

    // if not focused anymore
    // then hide all characters
    if(!hasFocus()) {
        QLineEdit::paintEvent(event);
        return;
    }

    // first paint as the default QLineEdit all characters but the last one
    const QString first_characters = text().chopped(1);
    const QString last_character = text().last(1);
    setText(first_characters);

    QLineEdit::paintEvent(event);

    // restore the full text
    setText(first_characters+last_character);

    // ensure font() is up to date
    ensurePolished();

    // then, draw the last character
    // &. compute the cursor position
    const QRect cr = cursorRect();
    const QPoint pos = cr.topRight() - QPoint(cr.width(), 0.);

    // create the QTextLayout and add the last character to it
    QTextLayout l(last_character, font());
    l.beginLayout();
    QTextLine line = l.createLine();
    line.setLineWidth(width() - pos.x());
    line.setPosition(pos);
    l.endLayout();

    QPainter p(this);
    // set text color to match the textedit text color
    p.setPen(palette().text().color());
    l.draw(&p, QPoint(0, 0));
}

lineeditvanishingcharacters.h

#ifndef LINEEDITVANISHINGCHARACTERS_H
#define LINEEDITVANISHINGCHARACTERS_H

#include <QLineEdit>
#include <QPaintEvent>

class LineEditVanishingCharacters : public QLineEdit
{
    Q_OBJECT

public:
    LineEditVanishingCharacters(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event);
};

#endif // LINEEDITVANISHINGCHARACTERS_H
qt qlineedit
1个回答
0
投票

这是我的解决方案。最后一个字符在 500 毫秒后隐藏。

lineeditvanishingcharacters.cpp

#include "lineeditvanishingcharacters.h"

#include <QTextLayout>
#include <QPainter>

LineEditVanishingCharacters::LineEditVanishingCharacters(QWidget *parent)
    : QLineEdit(parent)
    , m_is_new_character(false)
{
    setEchoMode(QLineEdit::Password);

    connect(this, &LineEditVanishingCharacters::textEdited,
            this, &LineEditVanishingCharacters::textHasBeenEdited);

    m_timer = new QTimer(this);
    connect(m_timer, &QTimer::timeout, this, [this]() {
        update();
        m_is_new_character = false;
    });
    m_timer->start(500); // 0.5 second
}

void LineEditVanishingCharacters::textHasBeenEdited()
{
    m_is_new_character = true;
    m_timer->start();
}

void LineEditVanishingCharacters::paintEvent(QPaintEvent *event)
{
    // first paint as the default QLineEdit all characters but the last one
    if(text().isEmpty()) {
        QLineEdit::paintEvent(event);
        return;
    }

    // no new character has been typed, then hide the full text
    if(!m_is_new_character) {
        QLineEdit::paintEvent(event);
        return;
    }

    // if not focused anymore
    // then hide all characters
    if(!hasFocus()) {
        QLineEdit::paintEvent(event);
        return;
    }

    const QString first_characters = text().chopped(1);
    const QString last_character = text().last(1);
    setText(first_characters);

    QLineEdit::paintEvent(event);

    // restore the full text
    setText(first_characters+last_character);

    // ensure font() is up to date
    ensurePolished();

    // then, draw the last character
    // &. compute the cursor position
    const QRect cr = cursorRect();
    const QPoint pos = cr.topRight() - QPoint(cr.width(), 0.);

    // create the QTextLayout and add the last character to it
    QTextLayout l(last_character, font());
    l.beginLayout();
    QTextLine line = l.createLine();
    line.setLineWidth(width() - pos.x());
    line.setPosition(pos);
    l.endLayout();

    QPainter p(this);
    // set text color to match the textedit text color
    p.setPen(palette().text().color());
    l.draw(&p, QPoint(0, 0));
}

lineeditvanishingcharacters.h

#ifndef LINEEDITVANISHINGCHARACTERS_H
#define LINEEDITVANISHINGCHARACTERS_H

#include <QLineEdit>
#include <QPaintEvent>

class LineEditVanishingCharacters : public QLineEdit
{
    Q_OBJECT

public:
    LineEditVanishingCharacters(QWidget *parent = nullptr);

public Q_SLOTS:
    void textHasBeenEdited();

protected:
    void paintEvent(QPaintEvent *event);

private:
    bool m_is_new_character;
};

#endif // LINEEDITVANISHINGCHARACTERS_H
© www.soinside.com 2019 - 2024. All rights reserved.