Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QLineEdit paint a different text than the actual text (placeholder with text() non-empty)

Tags:

c++

qt

I want my QLineEdit subclass to paint a different text (actually, HTML) than the real text.

More specifically, when the cursor is at end of string, it should paint as if the (HTML) text would be text() + "<font color='gray'>ThisIsExtraText</font>":

enter image description here

How can this be achieved?

I'm thinking about overriding the paint() method, but I don't really need to change any paint behavior, just that it should paint a different text.

However, I want that by all means, the text() property of the widget holds the real text, and not the modified text.

More details: the behavior I'm trying to implement is similar to placeholder text, but it is displayed when there is some text in the line-edit widget (unlike the placeholder, which is displayed when there is NO text).


A few problems I encountered:

QLineEdit does not accept HTML. I was thinking I can render the QLineEdit in two passes:

void MyLineEdit::paintEvent(QPaintEvent *event)
{
    if(cursorPosition() == text().length())
    {
        bool oldBlockSignals = blockSignals(true);

        // save old state:
        QString oldText = text();
        QString oldStyleSheet = styleSheet();
        bool oldReadOnly = isReadOnly();

        // change state:
        setText(oldText + "ThisIsExtraText");
        setStyleSheet("color: gray");
        setReadOnly(true);

        // paint changed state:
        QLineEdit::paintEvent(event);

        // restore state:
        setText(oldText);
        setStyleSheet(oldStyleSheet);
        setReadOnly(oldReadOnly);

        blockSignals(oldBlockSignals);
    }
    QLineEdit::paintEvent(event);
}

but the paintEvent would clear the background.

Even if I give up changing the color, the text is rendered with the cursor in the wrong position.

like image 470
fferri Avatar asked Oct 14 '25 20:10

fferri


1 Answers

Implementation of @joe_chip's answer:

void MyLineEdit::paintEvent(QPaintEvent *event)
{
    QLineEdit::paintEvent(event);

    if(!hasFocus()) return;
    if(cursorPosition() < txt.length()) return;

    ensurePolished(); // ensure font() is up to date

    QRect cr = cursorRect();
    QPoint pos = cr.topRight() - QPoint(cr.width() / 2, 0);

    QTextLayout l("ThisIsExtraText", font());
    l.beginLayout();
    QTextLine line = l.createLine();
    line.setLineWidth(width() - pos.x());
    line.setPosition(pos);
    l.endLayout();

    QPainter p(this);
    p.setPen(QPen(Qt::gray, 1));
    l.draw(&p, QPoint(0, 0));
}
like image 131
fferri Avatar answered Oct 17 '25 08:10

fferri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!