简体   繁体   English

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

[英]Change color of placeholder text in QLineEdit

When I set the placeholder text with QLineEdit::setPlaceholderText() , it appears gray.当我使用QLineEdit::setPlaceholderText()设置占位符文本时,它显示为灰色。

在此处输入图片说明

Is there any way to change the color to something else, for example red?有没有办法将颜色更改为其他颜色,例如红色?

You'll have to subclass QLineEdit and paint your own placeholder in the paintEvent() . 您必须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;
};

There is another a bit hacky but simple and reliable way. 还有一个有点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
    }
}

also you can use this way to derived from QLineEdit class 你也可以用这种方式从QLineEdit类派生

You can't , at least with the current QLineEdit code. 你不能 ,至少使用当前的QLineEdit代码。

As you can see from the source code, the placeholder text is simply taking the foreground brush of the palette and making it partially transparent, see QLineEdit::paintEvent : 从源代码中可以看出,占位符文本只是简单地获取调色板的前景画笔并使其部分透明,请参阅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);
    }
}

You can work with upstream into a more general solution, though. 但是,您可以将上游工作转换为更通用的解决方案。 In particular I one would expect that color to be added to the palette, or in general provided by the current QStyle (for instance as a style hint ). 特别是我希望将颜色添加到调色板中,或者通常由当前QStyle (例如作为样式提示 )。

If you want to change placeholder text color for a QLineEdit you have to customize the component's QPalette object. 如果要更改QLineEdit占位符文本颜色,则必须自定义组件的QPalette对象。

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 recall exactly which QPalette::ColorRole is appropriate for changing QLineEdit 's placeholder text color though. 我不记得究竟哪个QPalette::ColorRole适合更改QLineEdit的占位符文本颜色。

If you want to use QSS instead of QPalette, try the following: 如果您想使用QSS而不是QPalette,请尝试以下操作:

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

You can change the color, but bare in mind there is an alpha factor set in the placeholder from the source code (as mentioned in another comment) that cannot be removed. 您可以更改颜色,但请记住,源代码中的占位符设置了alpha因子(如另一条评论中所述),无法删除。 Therefore you will always see the placeholder darker (no white possible with this option). 因此,您将始终看到占位符较暗(使用此选项不可能出现白色)。

@Meefte solution is quite good given the situation that Qt gives placeholder the same color as for the text, except it adds 50% opacity. 考虑到Qt给占位符颜色与文本相同的情况,@ Meefte解决方案非常好,除了它增加了50%的不透明度。 So, there is little choice to set placeholder color to be different than the text. 因此,几乎没有选择将占位符颜色设置为与文本不同。 However, even this solution could be improved by making sure that you would not need to set some other variable than the default one Qt provides you. 但是,即使是这个解决方案也可以通过确保您不需要设置其他变量而不是Qt为您提供的默认变量来改进。

The need to use default placeholderText() might arise from the situation when you have lots of QLineEdit controls which are already promoted to some control overriding QLineEdit behavior, and placeholderText() is already set through code or through Qt Creator, ie it would be a bit painful to introduce another dynamic property. 当你有许多QLineEdit控件已被提升为某些控件覆盖QLineEdit行为,并且placeholderText()已经通过代码或通过Qt Creator设置时,可能会出现使用默认placeholderText()的需要,即它将是一个引入另一个动态属性有点痛苦。 However, if you did not promote to some child control, then it would be a necessity to do so in order to use such solution. 但是,如果您没有促进某些儿童控制,那么为了使用这种解决方案,这样做是必要的。

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

QT still has this problem) I solved it like this: QT还是有这个问题)我是这样解决的:

bool CustomLineEdit::event(QEvent *event)
{
    bool eventResult = QLineEdit::event(event);

    if (event->type() == QEvent::StyleChange) {
         QPalette pal = palette();
         pal.setColor(QPalette::PlaceholderText, Qt::red);
        setPalette(pal);
    }
    return eventResult;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM