QLineEdit 绘制与实际文本不同的文本(text() 非空占位符)

ffe*_*rri 3 c++ qt

我希望我的 QLineEdit 子类绘制与真实文本不同的文本(实际上是 HTML)。

更具体地说,当光标位于字符串末尾时,它应该像(HTML)文本一样绘制text() + "<font color='gray'>ThisIsExtraText</font>"

在此处输入图片说明

如何做到这一点?

我正在考虑覆盖 paint() 方法,但我真的不需要更改任何绘制行为,只是它应该绘制不同的文本。

但是,我无论如何都希望小部件的 text() 属性保存真实文本,而不是修改后的文本。

更多细节:我试图实现的行为类似于占位符文本,但它在行编辑小部件中有一些文本时显示(与占位符不同,它在没有文本时显示)。


我遇到的几个问题:

QLineEdit 不接受 HTML。我在想我可以分两次渲染 QLineEdit:

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);
}
Run Code Online (Sandbox Code Playgroud)

但paintEvent 会清除背景。

即使我放弃更改颜色,文本也会在光标位置错误的情况下呈现。

ffe*_*rri 5

@joe_chip 答案的实现:

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));
}
Run Code Online (Sandbox Code Playgroud)