我希望我的 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 会清除背景。
即使我放弃更改颜色,文本也会在光标位置错误的情况下呈现。
@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)