将巨大的文本缓冲区加载到QPlainTextEdit中

时间:2019-08-12 07:48:23

标签: c++ qt

QPlainTextEdit小部件中显示巨大文本缓冲区的正确最佳方法是什么?我的意思是听滚动条的移动事件,并根据当前滚动条的位置动态地仅将文本的可见部分传递给小部件。

我无法使用setPlainText将整个缓冲区发送到窗口小部件,因为文本缓冲区的大小超过1 GB,并且该函数获取了它的副本,这使内存使用量增加了一倍。

1 个答案:

答案 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()来检测用户是否到达了所显示部分的开头或结尾。例如,如果用户已到达末尾,您将获得光标位置,并使用它来设置以下部分而不是当前部分(也许使用重叠部分以使技巧更平滑)。