qtuser-interfacepyqtqlineedit

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


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


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.