【问题标题】:QTextLayout::drawCursor() does not work when subclassing QAbstractTextDocumentLayout子类化 QAbstractTextDocumentLayout 时 QTextLayout::drawCursor() 不起作用
【发布时间】:2017-11-01 13:38:13
【问题描述】:

目前QTextEditQPlainTextEdit不符合我的要求,所以我需要子类QAbstractTextDocumentLayout来提供文档的自定义布局。我参考了很多QPlainTextDocumentLayoutQTextDocumentLayout,最后得到了一个简单的布局来显示文本。但是,我在QTextEdit 中看不到光标,它应该在闪烁。我需要帮助来解决这个问题。

我使用的是 Qt 5.9.1。简单的项目是hereVTextDocumentLayoutdraw() 函数如下所示:

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

【问题讨论】:

    标签: qt qtextedit qtextdocument


    【解决方案1】:

    PaintContextcursorPosition的默认值为-1。

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

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

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

    【讨论】:

    • 嗨!我打印日志,可以看到cursorPosition-119 之间交替,我认为这对应于光标的闪烁。奇怪的是我在 Linux 中看不到光标,但在 Windows 中总是看到光标(不闪烁)。
    • 您能帮忙克隆这个简单的项目并运行一下吗?我真的很感谢你的帮助! :) 谢谢!
    • 肯定会试一试
    • 似乎我错误地实现了blockBoundingRect()QPlainTextDocumentLayout 仅返回具有 x 和 y 的边界矩形 0QAbstractTextDocumentLayout 不接受。在blockBoundingRect() 中返回几何矩形后,一切似乎都OK~ 谢谢!待我说清楚后再更新问题。
    【解决方案2】:

    当子类化QAbstractTextDocumentLayout 时,blockBoundingRect() 应该返回块的几何,而不仅仅是像QPlainTextDocumentLayout 那样的矩形。

    总之,QPlainTextDocumentLayout 提供了一个 BAD 示例,用于子类化QAbstractTextDocumentLayout

    【讨论】:

      猜你喜欢
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 2019-04-15
      相关资源
      最近更新 更多