QLineEdit: How to show a processed text
-
Hi :-)
A QLineEdit can show dots or stars instead of the entered text when one sets it to password mode. Is it also possible to display a custom processed text?
My specific use case would be to show a small dot (or similar) instead of spaces so that they are visualized.
As far as I can grasp it, one can only read the displayed text, but not set it and one can only set an echo mode from an existing enum. Apparently, the generation of the displayed text happens in non-public parts of the class, so I also can't override it.
Is it possible to implement a custom echo mode? Thanks for all hints!
-
Hi,
If I understand correctly you can do that using a proxy style:
class ProxyStyle : public QProxyStyle { int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override { if (hint == QStyle::SH_LineEdit_PasswordCharacter) { return QChar('$').unicode(); } return QProxyStyle::styleHint(hint, option, widget, returnData); } };
Set it on your QLineEdit and the echo char used will be a $ but you can change it to your liking.
-
@SGaist Thanks for the hint with
QProxyStyle
, but I don't think this is what I need … this will only change the displayed character for the password display, won't it?I want e. g. to enter
some text with spaces in between
and what theQLineEdit
should display would e. g. besome·text·with·spaces·in·between
, simply the space characters replaced with some visible characters. But when requestingtext()
, I want to have the actually entered text, not the displayed one. -
@l3u_ said in QLineEdit: How to show a processed text:
Qt Linguist
Hi
You can look around here
https://code.woboq.org/qt5/qttools/src/linguist/linguist/ -
Hi
For the fun of it i tried the obvious thing.class NoSpaceLineEdit : public QLineEdit { Q_OBJECT public: explicit NoSpaceLineEdit(QWidget *parent = nullptr) : QLineEdit(parent){} protected: virtual void paintEvent(QPaintEvent *e) override { setText(text().replace(' ', '*')); QLineEdit::paintEvent(e); } };
which does display * for space but also kills selection as setText resets it, so
its a no go. -
I ended up with the following (a bit hacky ;-) solution (I used
QPlainTextEdit
anyway in my project, so I chose this one):Edit: One also has to process pasted data so that no newline can be added
SpacesLineEdit.h:
#include <QPlainTextEdit> class SpacesLineEdit : public QPlainTextEdit { Q_OBJECT public: explicit SpacesLineEdit(QWidget *parent = nullptr); protected: virtual void keyPressEvent(QKeyEvent *event) override; virtual QSize sizeHint() const override; virtual QSize minimumSizeHint() const override; virtual void insertFromMimeData(const QMimeData *source) override; private: QSize m_sizeHint; };
SpacesLineEdit.cpp:
#include "SpacesLineEdit.h" #include <QLineEdit> SpacesLineEdit::SpacesLineEdit(QWidget *parent) : QPlainTextEdit(parent) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setLineWrapMode(QPlainTextEdit::NoWrap); setTabChangesFocus(true); QTextOption option = document()->defaultTextOption(); option.setFlags(option.flags() | QTextOption::ShowTabsAndSpaces); document()->setDefaultTextOption(option); // Stealing the sizeHint from a plain QLineEdit will do for now :-P QLineEdit lineEdit; m_sizeHint = lineEdit.sizeHint(); } QSize SpacesLineEdit::minimumSizeHint() const { return m_sizeHint; } QSize SpacesLineEdit::sizeHint() const { return m_sizeHint; } void SpacesLineEdit::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { event->ignore(); return; } QPlainTextEdit::keyPressEvent(event); } void SpacesLineEdit::insertFromMimeData(const QMimeData *source) { QString text = source->text(); text.replace(QLatin1String("\r\n"), QLatin1String(" ")); text.replace(QLatin1Char('\n'), QLatin1String(" ")); text.replace(QLatin1Char('\r'), QLatin1String(" ")); QMimeData processedSource; processedSource.setText(text); QPlainTextEdit::insertFromMimeData(&processedSource); }
Works fine … only question would be how to implement the
sizeHint
andminimalSizeHint
in a "correct" way ;-) I couldn't adapt the implementation from Linguist … also, I couldn't take the functions fromQLineEdit
, as they access d pointer private stuff …