我希望我的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);
}
但paintEvent会清除背景。
即使我放弃更改颜色,文本也会在光标位于错误的位置时呈现。
答案 0 :(得分:4)
实施@ 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));
}
答案 1 :(得分:3)
QLineEdit
在内部使用QTextLayout
进行渲染。你可以用它
为"ThisIsExtraText"
创建QTextLayout
实例,并从paintEvent
的{{1}}子类中提取实例。