Change color of placeholder text in QLineEdit

When I set the placeholder text with QLineEdit::setPlaceholderText()

, it looks gray.

enter image description here

Is there a way to change the color to something else like red?

+3


source to share


5 answers


You can't , at least with the current QLineEdit code.

As you can see from the source code, the placeholder text simply takes the foreground brush of the palette and makes it partially transparent, see QLineEdit::paintEvent

:



if (d->shouldShowPlaceholderText()) {
    if (!d->placeholderText.isEmpty()) {
        QColor col = pal.text().color();
        col.setAlpha(128);
        QPen oldpen = p.pen();
        p.setPen(col);
        QRect ph = lineRect.adjusted(minLB, 0, 0, 0);
        QString elidedText = fm.elidedText(d->placeholderText, Qt::ElideRight, ph.width());
        p.drawText(ph, va, elidedText);
        p.setPen(oldpen);
    }
}

      

However, you can work upstream into a more general solution. In particular, one would expect a color to be added to the palette, or even rendered current QStyle

(like a hint style , for example ).

+2


source


You will need a subclass QLineEdit

and draw your own placeholder in paintEvent()

.



class CustomColorPlaceholderLineEdit : public QLineEdit
{
public:
    CustomColorPlaceholderLineEdit(QWidget * parent = 0) : QLineEdit(parent) { color = QColor(0,0,0,128); }
    void setCustomPlaceholderText(const QString &text) { this->mText = text; }
    const QString &customPlaceholderText() const { return mText; }
    void setCustomPlaceholderColor(const QColor &color) { this->color = color; }
    const QColor &customPlaceholderColor() const { return color; }
    void paintEvent(QPaintEvent *event) {
        QLineEdit::paintEvent(event);
        if (!hasFocus() && text().isEmpty() && !mText.isEmpty()) {
            // QLineEdit own placeholder clashes with ours.
            Q_ASSERT(placeholderText().isEmpty());
            QPainter p(this);
            p.setPen(color);
            QFontMetrics fm = fontMetrics();
            int minLB = qMax(0, -fm.minLeftBearing());
            QRect lineRect = this->rect();
            QRect ph = lineRect.adjusted(minLB + 3, 0, 0, 0);
            QString elidedText = fm.elidedText(mText, Qt::ElideRight, ph.width());
            p.drawText(ph, Qt::AlignVCenter, elidedText);
        }
    }
private:
    QString mText;
    QColor color;
};

      

+5


source


There is still a little hackish, but simple and reliable way.

connect(lineEdit, &QLineEdit::textChanged, this, &YourClass::updateLineEditStyleSheet);

void YourLineEdit::updateLineEditStyleSheet()
{
    if (lineEdit->text().isEmpty()) {
        lineEdit->setStyleSheet("#lineEdit { color: lightGray;"); // Set your color but remember that Qt will reduce alpha
    } else {
        lineEdit->setStyleSheet("#lineEdit { color: black;"); // usual color
    }
}

      

also you can use this way to output from QLineEdit class

+2


source


If you want to change the color of the placeholder text for QLineEdit, you need to customize the QPalette component.

QPalette p = lineEdit->palette();
p.setColor(QPalette::Mid, Qt::red); // assuming Mid is the color you want to change.
lineEdit->setPalette(p);

      

I don't remember exactly which QPalette :: ColorRole is appropriate for changing the color of the fill text of a QLineEdit.

+1


source


Decision

@Meefte is pretty good considering Qt gives the placeholder the same color as text, except it adds 50% opacity. Thus, there is no choice to set the color of the bookmarks other than text. However, even this solution could be improved by making sure you don't need to set any other variable than the one provided by Qt by default.

The need to use defaultplaceholderText () may arise due to a situation where you have many QLineEdit controls that are already promoted to some control that overrides the behavior of QLineEdit, and placeholderText () is already set through code or through Qt Creator, that is, there would be a little it is painful to introduce another dynamic property. However, if you are not promoting any child control then it would be necessary to do so for that.

class CustomColorPlaceholderLineEdit : public QLineEdit
{
public:
    CustomColorPlaceholderLineEdit(QWidget * parent = 0) : QLineEdit(parent) { color = QColor(0,0,0,128); }

    const QString &customPlaceholderText() const { return mText; }

    void setCustomPlaceholderColor(const QColor &color) { this->color = color; }

    const QColor &customPlaceholderColor() const { return color; }

    void paintEvent(QPaintEvent *event)
    {
        if(color.isValid() && text().isEmpty() && (!placeholderText().isEmpty() || !mText.isEmpty()))
        {
            if(!placeholderText().isEmpty())
            {
                // In this way, placeholderText() is taken into local variable 'mText' care. Whenever placeholderText() will change, there it will be taken care of.
                mText = placeholderText();

                // This will ensure Qt will not draw placeholder for us.
                setPlaceholderText("");
            }

            // By this, we make sure Qt will paint QLineEdit default parts properly.
            QLineEdit::paintEvent(e);

            // And now @Meefte code is reused here.
            QPainter p(this);
            p.setPen(color);
            QFontMetrics fm = fontMetrics();
            int minLB = qMax(0, -fm.minLeftBearing());
            QRect lineRect = this->rect();
            QRect ph = lineRect.adjusted(minLB + 3, 0, 0, 0);
            QString elidedText = fm.elidedText(mText, Qt::ElideRight, ph.width());
            p.drawText(ph, Qt::AlignVCenter, elidedText);
            return; // No need to paint again.
        }

        // Default Qt painting behavior for QLineEdit.
        QLineEdit::paintEvent(e);
    }
private:
    QString mText;
    QColor color;
};

      

0


source







All Articles