2014-12-01 2 views
3

Когда я установил текст заполнителя QLineEdit::setPlaceholderText(), он выглядит серым.Изменить цвет текста заполнителя в QLineEdit

enter image description here

Есть ли способ изменить цвет на что-то другое, например, красный?

+0

Вам необходимо реализовать собственную функцию покраски заполнителя. Вы можете посмотреть в Qt, как это работает. Это очень просто. –

+0

[Здесь] (https://github.com/Vitallium/qt5/blob/master/qtbase/src/widgets/widgets/qlineedit.cpp#L1804) вы можете увидеть, как он обрабатывается в источнике 'QLineEdit' код. В основном это просто цвет текста и уменьшает альфу. – thuga

+0

Я отредактировал вопрос, чтобы сделать его более общим и понятным. – alediaferia

ответ

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).

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 все же.

+0

Этот код не работает - я тестировал его, цвет текста остается серым. Я начал щедрость по этому вопросу. – sashoalm

5

Вы должны подклассифицировать 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; 
}; 
+0

Я бы не рекомендовал идти этим путем. Это очень хрупкий хак, поскольку вы в основном перекрашиваете существующий текст заполнителя.Что, если Qt решает тонко настроить стиль и перемещать материал вокруг пикселя или около того? Что делать, если условие, которое проверяет, должно ли местозапись быть окрашено, меняется? (В частности, тот, что в этом коде неправильный.) – peppe

+0

@peppe Стандартный текст заполнителя Qt не существует. При определенных условиях я рисую пользовательский текст над QLineEdit. И вы можете изменить условие на все, что захотите. – Meefte

+0

@peppe У меня есть идея - вы можете просто изменить цвет текста в событии onFocus() - изменить его на пользовательский цвет при отпускании фокуса и изменить его обратно на ввод фокуса. – sashoalm

2

Существует еще немного хакерский, но простой и надежный способ.

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

0

@Meefte решение довольно хорошо, учитывая ситуацию, что Qt дает заполнителя такой же цвет, как и для текста, за исключением того, что добавляет 50% непрозрачности. Таким образом, нет выбора, чтобы установить цвет закладок, отличный от текста. Однако даже это решение можно было бы улучшить, убедившись, что вам не нужно будет устанавливать какую-либо другую переменную, кроме той, которую предоставляет Qt по умолчанию.

Необходимость использования default 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; 
}; 
Смежные вопросы