在QLineEdit中更改占位符文本的颜色

时间:2014-12-01 08:14:10

标签: c++ qt qlineedit

当我使用QLineEdit::setPlaceholderText()设置占位符文字时,它显示为灰色。

enter image description here

有没有办法将颜色更改为其他颜色,例如红色?

6 个答案:

答案 0 :(得分:6)

您必须继承QLineEdit并在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's 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;
};

答案 1 :(得分:4)

另一种有点hacky但简单可靠的方式。

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
    }
}

你也可以用这种方式从QLineEdit类派生

答案 2 :(得分:2)

你不能,至少使用当前的QLineEdit代码。

从源代码中可以看出,占位符文本只是简单地使用调色板的前景画笔并使其部分透明,请参阅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);
    }
}

但是,您可以将上游工作转换为更通用的解决方案。特别是我希望将颜色添加到调色板中,或者通常由当前QStyle提供(例如作为style hint)。

答案 3 :(得分:1)

如果要更改QLineEdit的占位符文字颜色,则必须自定义组件的QPalette对象。

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

我不记得究竟哪个QPalette::ColorRole适合更改QLineEdit的占位符文字颜色。

答案 4 :(得分:1)

如果要使用QSS而不是QPalette,请尝试以下操作:

setStyleSheet("QLineEdit{"
              "    color: red;" //TEXT COLOR
              "}"
              "QLineEdit[text=\"\"]{"
              "    color: gray;" //TEXTHOLDER COLOR
              "}");
connect(ui->lineEdit, &QLineEdit::textChanged, [=]{ style()->polish(ui->lineEdit); });

您可以更改颜色,但是请记住,源代码中的占位符中设置了一个alpha因子(如另一条注释中所述),无法删除。因此,您将始终看到占位符较暗(此选项无法显示白色)。

答案 5 :(得分:0)

@Meefte解决方案是非常好的,因为Qt为占位符提供了与文本相同的颜色,除了它增加了50%的不透明度。因此,几乎没有选择将占位符颜色设置为与文本不同。但是,即使是这个解决方案也可以通过确保您不需要设置一些其他变量来改进,而不是Qt为您提供的默认变量。

当您有许多placeholderText()控件已被提升为某些控件覆盖QLineEdit行为时,可能会出现使用默认QLineEdit的情况,placeholderText()已经通过代码或通过Qt Creator设置,即引入另一个动态属性会有点痛苦。但是,如果你没有提升某些儿童控制权,那么为了使用这种解决方案,这样做是必要的。

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's painting behavior for QLineEdit.
        QLineEdit::paintEvent(e);
    }
private:
    QString mText;
    QColor color;
};