QTextLayout::drawCursor() 在子类化 QAbstractTextDocumentLayout 时不起作用
QTextLayout::drawCursor() does not work when subclassing QAbstractTextDocumentLayout
目前QTextEdit
和QPlainTextEdit
不符合我的要求,所以我需要继承QAbstractTextDocumentLayout
来提供文档的自定义布局。我参考了很多QPlainTextDocumentLayout
和QTextDocumentLayout
,终于得到了一个简单的布局来显示文本。但是,我在 QTextEdit
中看不到光标,它应该在闪烁。我需要帮助来解决这个问题。
我正在使用 Qt 5.9.1。简单项目是here。 VTextDocumentLayout
的 draw()
函数如下所示:
void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_context)
{
qDebug() << "VTextDocumentLayout draw()" << p_context.clip << p_context.cursorPosition << p_context.selections.size();
// Find out the blocks.
int first, last;
blockRangeFromRect(p_context.clip, first, last);
if (first == -1) {
return;
}
QTextDocument *doc = document();
QPointF offset(m_margin, m_blocks[first].m_offset);
QTextBlock block = doc->findBlockByNumber(first);
QTextBlock lastBlock = doc->findBlockByNumber(last);
qreal maximumWidth = m_width;
while (block.isValid()) {
const BlockInfo &info = m_blocks[block.blockNumber()];
const QRectF &rect = info.m_rect;
QTextLayout *layout = block.layout();
if (!block.isVisible()) {
offset.ry() += rect.height();
if (block == lastBlock) {
break;
}
block = block.next();
continue;
}
QTextBlockFormat blockFormat = block.blockFormat();
QBrush bg = blockFormat.background();
if (bg != Qt::NoBrush) {
fillBackground(p_painter, rect, bg);
}
auto selections = formatRangeFromSelection(block, p_context.selections);
QPen oldPen = p_painter->pen();
p_painter->setPen(p_context.palette.color(QPalette::Text));
layout->draw(p_painter,
offset,
selections,
p_context.clip.isValid() ? p_context.clip : QRectF());
// Draw the cursor.
int blpos = block.position();
int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen;
Q_ASSERT(p_context.cursorPosition >= -1);
if (drawCursor) {
int cpos = p_context.cursorPosition;
cpos -= blpos;
qDebug() << "draw cursor" << block.blockNumber() << blpos << bllen << p_context.cursorPosition << cpos;
layout->drawCursor(p_painter, offset, cpos);
}
p_painter->setPen(oldPen);
offset.ry() += rect.height();
if (block == lastBlock) {
break;
}
block = block.next();
}
}
我调用了 layout->drawCursor()
来绘制光标,但是这个函数似乎什么也没做。
感谢任何帮助!谢谢!
更新:
添加日志如下:
VTextDocumentLayout draw() QRectF(67,0 9x13) 19 0
block range 0 1
draw cursor 1 5 15 19 14
blockBoundingRect() 1 13 QRectF(0,0 75x17)
VTextDocumentLayout draw() QRectF(67,0 9x13) -1 0
block range 0 1
blockBoundingRect() 1 13 QRectF(0,0 75x17)
VTextDocumentLayout draw() QRectF(67,0 9x13) 19 0
当 运行 这个项目在 Linux 时,我看不到光标。但是,当 运行 它在 Windows 时,我可以看到光标但不闪烁。
更新:
似乎 QTextEdit
将错误的剪辑 rect 传递给布局。如果我只插入一行文本(文档中只有一个块),我可以看到闪烁的光标。很奇怪!!!
PaintContext
classcursorPosition
的默认值为-1。
http://doc.qt.io/qt-4.8/qabstracttextdocumentlayout-paintcontext.html#cursorPosition-var
如果没有为光标位置提供任何默认值(它是一个 public 变量),那么我的猜测是值仍然是 -1,并且 drawCursor
总是 false
(因为块位置索引最小值在最坏情况下为零)。
尝试将一些默认值设置为 PaintContext::cursorPosition
,这可能会显示光标。
当对 QAbstractTextDocumentLayout
进行子类化时,blockBoundingRect()
应该 return 块的 几何体 ,而不仅仅是像 [=12= 这样的矩形] 确实如此。
一言以蔽之,QPlainTextDocumentLayout
为 QAbstractTextDocumentLayout
.
提供了一个 BAD 示例
目前QTextEdit
和QPlainTextEdit
不符合我的要求,所以我需要继承QAbstractTextDocumentLayout
来提供文档的自定义布局。我参考了很多QPlainTextDocumentLayout
和QTextDocumentLayout
,终于得到了一个简单的布局来显示文本。但是,我在 QTextEdit
中看不到光标,它应该在闪烁。我需要帮助来解决这个问题。
我正在使用 Qt 5.9.1。简单项目是here。 VTextDocumentLayout
的 draw()
函数如下所示:
void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_context)
{
qDebug() << "VTextDocumentLayout draw()" << p_context.clip << p_context.cursorPosition << p_context.selections.size();
// Find out the blocks.
int first, last;
blockRangeFromRect(p_context.clip, first, last);
if (first == -1) {
return;
}
QTextDocument *doc = document();
QPointF offset(m_margin, m_blocks[first].m_offset);
QTextBlock block = doc->findBlockByNumber(first);
QTextBlock lastBlock = doc->findBlockByNumber(last);
qreal maximumWidth = m_width;
while (block.isValid()) {
const BlockInfo &info = m_blocks[block.blockNumber()];
const QRectF &rect = info.m_rect;
QTextLayout *layout = block.layout();
if (!block.isVisible()) {
offset.ry() += rect.height();
if (block == lastBlock) {
break;
}
block = block.next();
continue;
}
QTextBlockFormat blockFormat = block.blockFormat();
QBrush bg = blockFormat.background();
if (bg != Qt::NoBrush) {
fillBackground(p_painter, rect, bg);
}
auto selections = formatRangeFromSelection(block, p_context.selections);
QPen oldPen = p_painter->pen();
p_painter->setPen(p_context.palette.color(QPalette::Text));
layout->draw(p_painter,
offset,
selections,
p_context.clip.isValid() ? p_context.clip : QRectF());
// Draw the cursor.
int blpos = block.position();
int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen;
Q_ASSERT(p_context.cursorPosition >= -1);
if (drawCursor) {
int cpos = p_context.cursorPosition;
cpos -= blpos;
qDebug() << "draw cursor" << block.blockNumber() << blpos << bllen << p_context.cursorPosition << cpos;
layout->drawCursor(p_painter, offset, cpos);
}
p_painter->setPen(oldPen);
offset.ry() += rect.height();
if (block == lastBlock) {
break;
}
block = block.next();
}
}
我调用了 layout->drawCursor()
来绘制光标,但是这个函数似乎什么也没做。
感谢任何帮助!谢谢!
更新: 添加日志如下:
VTextDocumentLayout draw() QRectF(67,0 9x13) 19 0
block range 0 1
draw cursor 1 5 15 19 14
blockBoundingRect() 1 13 QRectF(0,0 75x17)
VTextDocumentLayout draw() QRectF(67,0 9x13) -1 0
block range 0 1
blockBoundingRect() 1 13 QRectF(0,0 75x17)
VTextDocumentLayout draw() QRectF(67,0 9x13) 19 0
当 运行 这个项目在 Linux 时,我看不到光标。但是,当 运行 它在 Windows 时,我可以看到光标但不闪烁。
更新:
似乎 QTextEdit
将错误的剪辑 rect 传递给布局。如果我只插入一行文本(文档中只有一个块),我可以看到闪烁的光标。很奇怪!!!
PaintContext
classcursorPosition
的默认值为-1。
http://doc.qt.io/qt-4.8/qabstracttextdocumentlayout-paintcontext.html#cursorPosition-var
如果没有为光标位置提供任何默认值(它是一个 public 变量),那么我的猜测是值仍然是 -1,并且 drawCursor
总是 false
(因为块位置索引最小值在最坏情况下为零)。
尝试将一些默认值设置为 PaintContext::cursorPosition
,这可能会显示光标。
当对 QAbstractTextDocumentLayout
进行子类化时,blockBoundingRect()
应该 return 块的 几何体 ,而不仅仅是像 [=12= 这样的矩形] 确实如此。
一言以蔽之,QPlainTextDocumentLayout
为 QAbstractTextDocumentLayout
.