子类化QAbstractTextDocumentLayout时,QTextLayout :: drawCursor()不起作用

时间:2017-11-01 13:38:14

标签: qt qtextedit qtextdocument

目前QTextEditQPlainTextEdit不符合我的要求,因此我需要将QAbstractTextDocumentLayout子类化以提供文档的自定义布局。我经常引用QPlainTextDocumentLayoutQTextDocumentLayout,最后得到一个简单的布局来显示文本。但是,我无法在QTextEdit中看到光标,它应该闪烁。我需要帮助来解决这个问题。

我正在使用Qt 5.9.1。简单的项目是heredraw()的{​​{1}}函数如下所示:

VTextDocumentLayout

我调用了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()

在Linux中运行这个项目时,我看不到光标。但是,在Windows中运行时,我可以看到光标但不闪烁。

更新: 似乎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 将错误的剪辑矩形传递给布局。如果我只插入一行文本(文档中只有一个块),我可以看到闪烁的光标。很奇怪!!!

2 个答案:

答案 0 :(得分:0)

PaintContextcursorPosition的默认值为-1。

http://doc.qt.io/qt-4.8/qabstracttextdocumentlayout-paintcontext.html#cursorPosition-var

如果没有向游标位置提供任何默认值(它是公共变量),那么我的猜测值仍为-1,drawCursor始终为false(作为块位置)在最坏的情况下,索引最小值为零。

尝试将一些默认值设置为PaintContext::cursorPosition,这可能会显示光标。

答案 1 :(得分:0)

在对QAbstractTextDocumentLayout进行子类化时,blockBoundingRect()应该返回块的几何,而不仅仅是QPlainTextDocumentLayout所做的矩形。

总之,QPlainTextDocumentLayout为子类QAbstractTextDocumentLayout提供了 BAD 示例。