如何在QT中提高QTextEdit :: setPlainText()的速度?

时间:2018-04-11 11:52:07

标签: c++ qt

我最近在Github上写了一个TextEditor project。该项目已完成纯文本编辑器的基本功能!

但是,我对打开大文件的速度感到不满意。

例如,在打开540KB文件时,readAll()的费用为18毫秒,但setPlainText()的费用为 42s ,这很烦人。如何提高代码性能?你能给我一些建议吗?提前谢谢。

我的主要代码如下:

// textedit.cpp 
#define qcout qDebug()
bool TextEditor::readFile(const QString &fileName)
{
    QFile file(fileName);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QMessageBox::warning(this, tr("TextEditor"),
                             tr("Cannot read file %1.\n%2.")
                             .arg(file.fileName())
                             .arg(file.errorString()));
        return false;
    }

    //QTextStream inFile(&file);
#ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
    QTime t1, t2, t3, t4;
    t1 = QTime::currentTime();
    const QByteArray data = file.readAll();     // 18ms
    t2 = QTime::currentTime();
    qcout << t1.msecsTo(t2);
    QTextCodec::ConverterState state;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    const QString text = codec->toUnicode(data.constData(), data.size(), &state);
    //qcout << text;
    t3 = QTime::currentTime();
    qcout << t2.msecsTo(t3);
    if (state.invalidChars > 0)
    {
        // Not a UTF-8 text - using system default locale
        QTextCodec * codec1 = QTextCodec::codecForLocale();
        qcout << codec1->name();
        if (!codec1)
            return false;
        qcout << "invalidChars > 0";
        setPlainText(codec1->toUnicode(data));
    }
    else
    {
        qcout << "invalidChars = 0";
        setPlainText(text);
    }
    t4 = QTime::currentTime();
    qcout << t3.msecsTo(t4);              // 42s annoying!
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif
    return true;
}

结果是:

18
1
invalidChars = 0
42126

1 个答案:

答案 0 :(得分:2)

测试文件的名称已经讲述了故事( longline.txt )。

性能损失是由于默认的自动换行模式( QTextOption :: WrapAtWordBoundaryOrAnywher e),它试图包装单词而不将它们切成两半。

由于您的文件基本上是一个非常长的单个“单词”,因此可怜的QTextEdit别无选择,只能扫描整个文件以寻找结尾。

如果在构造函数中添加以下行:

setWordWrapMode(QTextOption::WrapAnywhere);

您可以覆盖默认的换行模式。设置 QTextOption :: WrapAnywhere 时,可以在一行的任何位置进行换行(请查看文档here)。

仅供参考,我的机器只花了199毫秒来加载文件并显示它。

但是,由于这是一个非常不寻常的文本案例,我建议您使用真实世界的示例测试您的应用程序,或者至少通过UI向用户公开包装模式设置。