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

pyqt, qlineedit, qt, user-interface

Solution

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.

Problem

In Qt, a created `lineEdit` shows a text using the `setText()` method. But the cursor is movable for the default text. I want the cursor should not be movable for the default text. 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?

Original source