【问题标题】:Performantly appending (rich) text into QTextEdit or QTextBrowser in Qt在 Qt 中将(富)文本高效地附加到 QTextEdit 或 QTextBrowser
【发布时间】:2019-06-27 08:15:07
【问题描述】:

QTextEdit 可以简单地使用 append() 附加文本。但是,如果文档是富文本,则每次附加到文档时,它显然都会重新解析。这似乎是 Qt 中的一个陷阱。

如果您将编辑框用作日志窗口并根据外部信号快速连续附加文本,则附加可以轻松挂起您的应用,而不会显示任何中间附加,直到每个附加完成。

如何将富文本附加到 QTextEdit 而不降低整个 UI 的速度?

【问题讨论】:

    标签: c++ qt user-interface


    【解决方案1】:

    如果您希望每个附加内容快速且单独显示(而不是等到它们都被附加后才显示),您需要访问内部 QTextDocument:

    void fastAppend(QString message,QTextEdit *editWidget)
    {
        const bool atBottom = editWidget->verticalScrollBar()->value() == editWidget->verticalScrollBar()->maximum();
        QTextDocument* doc = editWidget->document();
        QTextCursor cursor(doc);
        cursor.movePosition(QTextCursor::End);
        cursor.beginEditBlock();
        cursor.insertBlock();
        cursor.insertHtml(message);
        cursor.endEditBlock();
    
        //scroll scrollarea to bottom if it was at bottom when we started
        //(we don't want to force scrolling to bottom if user is looking at a
        //higher position)
        if (atBottom) {
            scrollLogToBottom(editWidget);
        }
    }
    
    void scrollLogToBottom(QTextEdit *editWidget)
    {
    
        QScrollBar* bar =  editWidget->verticalScrollBar();
        bar->setValue(bar->maximum());
    }
    

    滚动到底部是可选的,但在记录使用时,它是 UI 行为的合理默认值。

    另外,如果您的应用同时进行大量其他处理,将其附加到 fastAppend 的末尾,将优先考虑尽快实际显示消息:

        //show the message in output right away by triggering event loop
        QCoreApplication::processEvents();
    

    这实际上似乎是 Qt 中的一种陷阱。我会知道为什么 QTextEdit 中没有直接的 fastAppend 方法?或者这个解决方案有什么注意事项?

    (我的公司实际上为这个建议向 KDAB 支付了费用,但这似乎很愚蠢,以至于我认为这应该是更普遍的知识。)

    【讨论】:

      猜你喜欢
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 2016-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多