使用 TextArea 和 ScrollView 显示大文本文件的性能问题
Performance problems with showing large text files using TextArea and ScrollView
用例:
我想使用 QML 或至少与 QML 兼容的组件显示大型日志文件(8k+ 行)。多行选择、复制和语法高亮等功能是必需的。
问题:
默认方法是在 ScrollView 中使用 TextArea,但问题是内存使用率高(在我的机器上选择了多行:2GB+)导致冻结(5 秒+)和崩溃。
示例代码:
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("TextEditTest")
ScrollView {
id: scrollView
anchors.fill: parent
TextArea {
id: textArea
text: " "
renderType: Text.NativeRendering
textFormat: Text.PlainText
placeholderText: "no text found"
readOnly: true
selectByMouse: true
}
}
}
(只需在 " " 中插入一些文本(8k+ 行)
问题:
TextArea + ScrollView 是否可以提高内存使用率?或者有其他选择吗?
可能的解决方案?:仍然使用 TextEdit,但提供自己的滚动功能,该功能可按需加载文本,从而防止一次呈现整个文本。问题是我必须在现有功能之上编写自己的选择和复制功能。
This comment from Jira总结了问题并提供了可能的解决方案:
Qt Quick's TextEdit will actually populate the scene graph with nodes for all glyphs, not just the visible ones. There is logic to isolate updates as much as possible, but all the geometry for all text has to be processed at least once and uploaded to the GPU, and draw calls will be generated for it.
So bottom line is that TextEdit is not suitable for texts at this size at the moment. Until this has been addressed, I would recommend to use a QQuickPaintedItem and QTextDocument instead.
This component 是 QScintilla 的 QML 端口,它更适合非常大的文件。
用例: 我想使用 QML 或至少与 QML 兼容的组件显示大型日志文件(8k+ 行)。多行选择、复制和语法高亮等功能是必需的。
问题: 默认方法是在 ScrollView 中使用 TextArea,但问题是内存使用率高(在我的机器上选择了多行:2GB+)导致冻结(5 秒+)和崩溃。
示例代码:
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("TextEditTest")
ScrollView {
id: scrollView
anchors.fill: parent
TextArea {
id: textArea
text: " "
renderType: Text.NativeRendering
textFormat: Text.PlainText
placeholderText: "no text found"
readOnly: true
selectByMouse: true
}
}
}
(只需在 " " 中插入一些文本(8k+ 行)
问题: TextArea + ScrollView 是否可以提高内存使用率?或者有其他选择吗?
可能的解决方案?:仍然使用 TextEdit,但提供自己的滚动功能,该功能可按需加载文本,从而防止一次呈现整个文本。问题是我必须在现有功能之上编写自己的选择和复制功能。
This comment from Jira总结了问题并提供了可能的解决方案:
Qt Quick's TextEdit will actually populate the scene graph with nodes for all glyphs, not just the visible ones. There is logic to isolate updates as much as possible, but all the geometry for all text has to be processed at least once and uploaded to the GPU, and draw calls will be generated for it.
So bottom line is that TextEdit is not suitable for texts at this size at the moment. Until this has been addressed, I would recommend to use a QQuickPaintedItem and QTextDocument instead.
This component 是 QScintilla 的 QML 端口,它更适合非常大的文件。