我在阅读文件时遇到问题,具体是我想制作一个小词典。在我需要阅读的文件中有这样的内容:

a   Ph  P6
a   snsr    CA
a b c   fb  Dj
a b c - book    i+  BS
A except B gate oOPa    y
a font  kQ  BU
[....]

它有大约 109.000 行,文件只有大约 2MB。在我的 QT 应用程序中,我这样编码以读取项目并将其添加到 QListWidget:
QString sWord;
QFile inFile("C:\\EV\\ev.index");

inFile.open(QIODevice::ReadOnly|QIODevice::Text);
QTextStream in(&inFile);
while(!in.atEnd())
{
     sWord = in.readLine();
     myListWidget->addItem(sWord); //myListWidget is a QListWidget
}

但是读得太长了!起初我认为原因是我的应用程序逐行读取,所以我再次编码如下:
QString data;
QStringList listWord;
QFile inFile("C:\\EV\\ev.index");


inFile.open(QIODevice::ReadOnly|QIODevice::Text);
QTextStream in(&inFile);
data.append(in.readAll());
listWord.append(data.split('\n'));
myListWidget->addItems(listWord);
inFile.close();

它工作得更快!(自应用程序启动后大约 5 秒),仍然很长,我希望它阅读速度更快。我必须做什么?

最佳答案

  • 列表小部件的布局时间太长。将列表小部件的 uniformItemSizes 属性设置为 true。这避免了昂贵的布局操作。另一种方法是将 layoutMode 属性设置为 QListView::Batched 。这避免了必须一次昂贵地布置所有项目。
  • 如果较低的开销 QListWidget 可以做到,请不要使用 QListView
  • 应批量添加大量元素,即不要将元素一一插入模型中。在仅发出 rowsInsertedcolumnsInserted 信号一次的原子操作中插入来自每个批次的元素。
  • 不得在 GUI 线程中加载任何文件。这是许多应用程序中糟糕的用户体验的一个来源,必须以大量的蔑视来劝阻。 不要这样做

  • 下面是一个将所有这些都考虑在内的最小示例。
    // https://github.com/KubaO/stackoverflown/tree/master/questions/filemodel-18548048
    #include <QtWidgets>
    #include <QtConcurrent>
    
    void makeLines(QBuffer &buf, int count = 1000000) {
       buf.open(QIODevice::WriteOnly | QIODevice::Text);
       char line[16];
       for (int i = 0; i < count; ++i) {
          int n = qsnprintf(line, sizeof(line), "Item %d\n", i);
          buf.write(line, n);
       }
       buf.close();
    }
    
    struct StringListSource : QObject {
       Q_SIGNAL void signal(const QStringList &);
       void operator()(const QStringList &data) { emit signal(data); }
       Q_OBJECT
    };
    
    int main(int argc, char *argv[]) {
       QApplication app(argc, argv);
       QListView view;
       QStringListModel model;
       StringListSource signal;
       QObject::connect(&signal, &StringListSource::signal, &model, &QStringListModel::setStringList);
       QtConcurrent::run([&signal]{
          QBuffer file;
          signal({"Generating Data..."});
          makeLines(file);
          signal({"Loading Data..."});
          QStringList lines;
          if (file.open(QIODevice::ReadOnly | QIODevice::Text))
             while (!file.atEnd())
                lines.append(QString::fromLatin1(file.readLine()));
          file.close();
          signal(lines);
       });
       view.setModel(&model);
       view.setUniformItemSizes(true);
       view.show();
       return app.exec();
    }
    #include "main.moc"
    

    关于qt - 当给定 100k 项时,QListView 需要很长时间才能更新,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18548048/

    10-13 04:06