英文:
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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论