QTextBrowser在新文本添加时滚动文本。

huangapple go评论126阅读模式
英文:

QTextbrowser Scroll through text whilst new text is still being added

问题

我有一个QTextBrowser小部件,并且我正在向这个小部件添加文本,就像下面的代码一样:

QTextBrowser m_outputLog;
...
void MainWindow::readStdout()
{
  if (m_running)
  {
    QByteArray data = m_runProcess->readAllStandardOutput();
    QString text = QString::fromUtf8(data);
    if (!text.isEmpty())
    {
      m_outputLog->moveCursor(QTextCursor::End);
      m_outputLog->insertPlainText(text);
      m_outputLog->moveCursor(QTextCursor::End);
    }
  }
}

readStdout 通过信号/槽机制连接到 m_outputLog。这一切都运行正常。文本被附加到末尾,不过缺点是,每次插入文本时,即使我已经向上滚动了一点,也会跳回末尾。当我删除 m_outputLog->moveCursor(QTextCursor::End); 语句时,文本仍然很好地附加到末尾,但没有自动显示文本,我总是必须使用鼠标向下滚动。

  • 如何将文本放在末尾
  • 在已经显示了文本末尾时如何自动显示新文本
  • 当我使用鼠标滚动文本时保持在滚动位置

有什么建议吗?

英文:

I have a QTextBrowser widget and I'm adding text to this widget like

QTextBrowser m_outputLog;
...
void MainWindow::readStdout()
{
  if (m_running)
  {
    QByteArray data = m_runProcess->readAllStandardOutput();
    QString text = QString::fromUtf8(data);
    if (!text.isEmpty())
    {
      m_outputLog->moveCursor (QTextCursor::End);
      m_outputLog->insertPlainText (text);
      m_outputLog->moveCursor (QTextCursor::End);
    }
  }
}

the readStdout is connected to the m_outputLog through the signal / slot mechanism.
This all works OK.
The text is appended at the end though the disadvantage is that with each insertion there is a jump back to the end even when I did scroll up a bit.
When I remove the m_outputLog->moveCursor (QTextCursor::End); statements the text is still nicely appended at the end but there is no automatic show of the text, I always have to use the mouse to scroll down.

  • how can I put the text at the end
  • automatically show the new text when the end of the text was already shown
  • stay at the scroll position when I used the mouse to scroll through the text

Any suggestions?

答案1

得分: 2

以下是我为满足自己需求所做的工作:

void appendLogMessage(const QString& message)
{
    QScrollBar vbar = verticalScrollBar();

    // 分析光标和滚动条位置
    const QTextCursor old_cursor = textCursor();
    const bool is_scrolled_down = vbar->value() == vbar->minimum();
    const int distanceFromBottom = vbar->maximum() - vbar->value();

    // 将光标移动到文档的开头。
    moveCursor(QTextCursor::Start);

    // 添加新文本
    textCursor().insertPlainText(message);

    if (old_cursor.hasSelection() || !is_scrolled_down)
    {
        // 文本已选中或者滚动条不在底部:保持位置不变。
        setTextCursor(old_cursor);
        vbar->setValue(vbar->maximum() - distanceFromBottom);
    }
    else
    {
        // 没有文本被选中且滚动条在顶部:滚动到顶部。
        moveCursor(QTextCursor::Start);
        vbar->setValue(verticalScrollBar()->minimum());
    }
}

基本上,您需要在添加新文本之前保存滚动条位置,然后根据您的条件决定是否将滚动条移回到此位置(例如,我决定仅在用户选择了某些文本时不移动滚动条)。

英文:

Here is what I have done for my own need:

void appendLogMessage(const QString& message)
{
    QScrollBar vbar = verticalScrollBar();

    // analyze cursor and scrollbar positions
    const QTextCursor old_cursor = textCursor();
    const bool is_scrolled_down = vbar->value() == vbar->minimum();
    const int distanceFromBottom = vbar->maximum() - vbar->value();

    // move the cursor to the begining of the document.
    moveCursor(QTextCursor::Start);

    // adding new text
    textCursor().insertPlainText(message);

    if (old_cursor.hasSelection() || !is_scrolled_down)
    {
        // text is selected or scrollbar is not anymore at the bottom: maintain position.
        setTextCursor(old_cursor);
        vbar->setValue(vbar->maximum() - distanceFromBottom);
    }
    else
    {
        // no text is selected and the scrollbar is at the top: scroll to the top.
        moveCursor(QTextCursor::Start);
        vbar->setValue(verticalScrollBar()->minimum());
    }
}

Basically, you need to save the scrollbar position before adding the new text, and then decide to move back the scrollbar to this position depending on your own criteria (for example, I decided not to move the scrollbar only if the user has selected some text).

huangapple
  • 本文由 发表于 2023年6月8日 17:35:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定