QLineEdit with some default text for which cursor should not be moved?
Asked Answered
B

4

10

In Qt, a created lineEdit shows a text using the setText() method.

  1. But the cursor is movable for the default text. I want the cursor should not be movable for the default text.

  2. My lineEdit type has been set as password. Hence the default text('Password') is also displayed as '********'. Whenever user types the type has to be changed as password and when there is no text or until the user have not typed any text, the lineEdit should display the plain text 'password'

Any idea to fix the above two issues? enter image description here

Brahman answered 21/5, 2012 at 6:41 Comment(0)
S
5

I managed to do what you want by deriving a class from QLineEdit as per following..

Constructor..

QCustomLineEdit::QCustomLineEdit(QWidget *parent) :
    QLineEdit(parent)
{
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
    connect(this, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onCursorPositionChanged(int,int)));

    setEchoMode(QLineEdit::Password);   // Echo mode in your case..

    m_echoMode = echoMode();            // Member variable to store original echo mode..
    m_placeHolderText = "Password";     // Member variable..
    m_isPlaceHolderActive = true;       // Member varible..

    // Default case..
    setPlaceholderText("");
    setStyleSheet("QCustomLineEdit{color: gray;}");
    setEchoMode(QLineEdit::Normal);
    setText(__placeHolderText);
}

Override keyPressEvent..

void QCustomLineEdit::keyPressEvent(QKeyEvent *e)
{
    if(m_isPlaceHolderActive)
    {
        if(e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace)
            e->accept();
        else
            QLineEdit::keyPressEvent(e);

        return;
    }

    QLineEdit::keyPressEvent(e);
}

Cursor position change event..

void QCustomLineEdit::onCursorPositionChanged(int /*oldPos*/, int newPos)
{
    if(m_isPlaceHolderActive)
    {
        if(newPos != 0)
            setCursorPosition(0);
    }
}

Text change event..

void QCustomLineEdit::onTextChanged(const QString &text)
{
    if(m_isPlaceHolderActive)
    {
        if(text.compare(m_placeHolderText) != 0)
        {
            m_isPlaceHolderActive = false;

            // Remove the 'placeHolderText' from 'text' itself..
            QString temp = text;
            temp = temp.mid(0, text.lastIndexOf(m_placeHolderText));

            setStyleSheet("QCustomLineEdit{color: black;}");
            setEchoMode(m_echoMode);
            setText(temp);
        }
        else
        {
            setEchoMode(QLineEdit::Normal);
            setText(m_placeHolderText);
            setStyleSheet("QCustomLineEdit{color: gray;}");
            setCursorPosition(0);
        }
    }
    else
    {
        if(text.isEmpty())
        {
            m_isPlaceHolderActive = true;
            setStyleSheet("QCustomLineEdit{color: gray;}");
            setEchoMode(QLineEdit::Normal);
            setText(m_placeHolderText);
        }
    }
}

I have written it very hastily to just show you. Test it yourself and feel free to point any mistake(s) or optimization(s). Hope this helps.

Soar answered 21/5, 2012 at 7:7 Comment(4)
setPlaceholderText() method works good. But whenever the qlineedit widget gets focussed or mouse clicked on qlineedit, default text get hidden. I want to display the default text even when the cursor is in the widget with the condition that the cursor should not be moved until the user type any text.Brahman
Ok. Remove ui->lineEdit->setText(""); and ui->lineEdit->setEchoMode(QLineEdit::Password); from on_lineEdit_selectionChanged(). And add ui->lineEdit->setEchoMode(QLineEdit::Password); in on_lineEdit_textEdited()Monteria
@Soar : Can i set my lineedit cursor color black when my default text color is grey. Is tat possible?Brahman
@user971306: If you see the source code of QLineEdit::paintEvent() then you will notice that cursor is drawn using QTextLayout::drawCursor() function, which uses current pen set in QPainter, which is text-color. So you can override that paintEvent() and set the appropriate pen-color before drawing cursor.. Bit tricky.. :)Soar
M
15

In the constructor put

ui->lineEdit->setPlaceholderText("password");
ui->lineEdit->setReadOnly(1);

And in on_lineEdit_selectionChanged() SLOT, put

ui->lineEdit->setText("");
ui->lineEdit->setEchoMode(QLineEdit::Password);
ui->lineEdit->setReadOnly(0);
Monteria answered 21/5, 2012 at 7:16 Comment(1)
Thanks spyke. setPlaceholderText() method works good. But whenever the qlineedit widget gets focussed or mouse clicked on qlineedit, default text get hidden. I want to display the default text even when the cursor is in the widget with the condition that the cursor should not be moved until the user type any text....Brahman
S
9

I noticed this question has tag pyqt so I'll put an actual answer related to that tag for those actually looking for a python way instead of c++.

self.searchEditText = QtGui.QLineEdit()
self.searchEditText.setPlaceholderText("Search for word")
Sharrisharron answered 21/2, 2017 at 23:20 Comment(0)
S
5

I managed to do what you want by deriving a class from QLineEdit as per following..

Constructor..

QCustomLineEdit::QCustomLineEdit(QWidget *parent) :
    QLineEdit(parent)
{
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
    connect(this, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onCursorPositionChanged(int,int)));

    setEchoMode(QLineEdit::Password);   // Echo mode in your case..

    m_echoMode = echoMode();            // Member variable to store original echo mode..
    m_placeHolderText = "Password";     // Member variable..
    m_isPlaceHolderActive = true;       // Member varible..

    // Default case..
    setPlaceholderText("");
    setStyleSheet("QCustomLineEdit{color: gray;}");
    setEchoMode(QLineEdit::Normal);
    setText(__placeHolderText);
}

Override keyPressEvent..

void QCustomLineEdit::keyPressEvent(QKeyEvent *e)
{
    if(m_isPlaceHolderActive)
    {
        if(e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace)
            e->accept();
        else
            QLineEdit::keyPressEvent(e);

        return;
    }

    QLineEdit::keyPressEvent(e);
}

Cursor position change event..

void QCustomLineEdit::onCursorPositionChanged(int /*oldPos*/, int newPos)
{
    if(m_isPlaceHolderActive)
    {
        if(newPos != 0)
            setCursorPosition(0);
    }
}

Text change event..

void QCustomLineEdit::onTextChanged(const QString &text)
{
    if(m_isPlaceHolderActive)
    {
        if(text.compare(m_placeHolderText) != 0)
        {
            m_isPlaceHolderActive = false;

            // Remove the 'placeHolderText' from 'text' itself..
            QString temp = text;
            temp = temp.mid(0, text.lastIndexOf(m_placeHolderText));

            setStyleSheet("QCustomLineEdit{color: black;}");
            setEchoMode(m_echoMode);
            setText(temp);
        }
        else
        {
            setEchoMode(QLineEdit::Normal);
            setText(m_placeHolderText);
            setStyleSheet("QCustomLineEdit{color: gray;}");
            setCursorPosition(0);
        }
    }
    else
    {
        if(text.isEmpty())
        {
            m_isPlaceHolderActive = true;
            setStyleSheet("QCustomLineEdit{color: gray;}");
            setEchoMode(QLineEdit::Normal);
            setText(m_placeHolderText);
        }
    }
}

I have written it very hastily to just show you. Test it yourself and feel free to point any mistake(s) or optimization(s). Hope this helps.

Soar answered 21/5, 2012 at 7:7 Comment(4)
setPlaceholderText() method works good. But whenever the qlineedit widget gets focussed or mouse clicked on qlineedit, default text get hidden. I want to display the default text even when the cursor is in the widget with the condition that the cursor should not be moved until the user type any text.Brahman
Ok. Remove ui->lineEdit->setText(""); and ui->lineEdit->setEchoMode(QLineEdit::Password); from on_lineEdit_selectionChanged(). And add ui->lineEdit->setEchoMode(QLineEdit::Password); in on_lineEdit_textEdited()Monteria
@Soar : Can i set my lineedit cursor color black when my default text color is grey. Is tat possible?Brahman
@user971306: If you see the source code of QLineEdit::paintEvent() then you will notice that cursor is drawn using QTextLayout::drawCursor() function, which uses current pen set in QPainter, which is text-color. So you can override that paintEvent() and set the appropriate pen-color before drawing cursor.. Bit tricky.. :)Soar
E
4

For question 1, in Qt 5.0 and higher, setPlaceholderText does what you want. https://codereview.qt-project.org/#change,45326

Electrocautery answered 28/1, 2014 at 2:1 Comment(2)
Please describe in short here what is given in the link. If you want to help, you could put this link in a comment. This doesn't look really like an answer right now.Gardal
I would add that setEchoMode(QLineEdit::Password) is also works really well with setPlaceholderText since Qt 5.4 and higher as wellVins

© 2022 - 2024 — McMap. All rights reserved.