在QPlainTextEdit
小部件中显示巨大文本缓冲区的正确和最佳方法是什么?我的意思是听滚动条的移动事件,并根据当前滚动条的位置动态地仅将文本的可见部分传递给小部件。
我无法使用setPlainText
将整个缓冲区发送到窗口小部件,因为文本缓冲区的大小超过1 GB,并且该函数获取了它的副本,这使内存使用量增加了一倍。
答案 0 :(得分:0)
假设您有1GB的数据,并且不想超出此内存负载,那么我认为您应该部分读取数据并将其附加到QPlainTextEdit
的缓冲区中。这样,您的大文本就不会超过1GB的内存使用量。
实际上,用于存储加载零件的临时变量将在每次迭代时删除,而您只需要在循环结束时销毁它即可。
此外,如果您只希望对可见部分进行不同的着色(如您在讨论中所述),我认为您应该对整个文本进行着色,因为仅会显示可见部分的颜色(与其他部分一样)被隐藏,它们的颜色无关紧要。
而且当您上下滚动时,文本已经按照您的意愿进行了着色,则您将无需执行任何操作。
因此,您将具有所需的行为,同时减少了计算开销,因为您不必在每次滚动事件时都执行变色任务。
以下是我的意思的最小,完整且可复制的示例:
#include <QApplication>
#include <QFile>
#include <QTextEdit>
#include <QDebug>
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
QFile data_file("path/to/data/file/some_data.txt");
if(!data_file.open(QIODevice::ReadOnly | QIODevice::Text))
return -1;
// ---------- ---------- ---------- ---------- ----------
// Set the text color
QTextEdit view;
view.setTextColor(Qt::darkGreen);
// read 100 chars by 100 chars (set the value you want)
unsigned int MAX_LEN(100);
// Create the temporary buffer
char * part = new char[MAX_LEN];
// Read the file part by part
qint64 readBytes;
while((readBytes = data_file.read(part, MAX_LEN)) > 0)
{
view.insertPlainText(QString(part).left(static_cast<int>(readBytes)));
}
// destroy the temporary buffer
delete[] part;
// ---------- ---------- ---------- ---------- ----------
data_file.close();
view.show();
return app.exec();
}
编辑:
如果将完整数据加载到QPlainTextEdit
中会使您的GUI速度大大降低,我认为您可以像以前一样加载数据,而只需在QPlainTextEdit
中设置部分数据即可。在滚动事件中,可以结合使用QPlainTextEdit::textCursor()
和QTextCursor::atStart()
和QTextCusrsor::atEnd()
来检测用户是否到达了所显示部分的开头或结尾。例如,如果用户已到达末尾,您将获得光标位置,并使用它来设置以下部分而不是当前部分(也许使用重叠部分以使技巧更平滑)。