3

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

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 秒),仍然很长,我希望它读得更快。我必须做什么?

4

1 回答 1

9
  1. 列表小部件的布局耗时过长。将列表小部件的uniformItemSizes属性设置为 true。这避免了昂贵的布局操作。另一种方法是将layoutMode属性设置为QListView::Batched. 这避免了一次昂贵地布置所有项目。

  2. QListWidget如果可以降低开销,请不要使用QListView

  3. 应批量添加大量元素,即不要将元素一个接一个地插入模型中。rowsInserted在仅发出一次orcolumnsInserted信号的原子操作中插入每个批次的元素。

  4. 您不得在 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"
于 2013-09-02T18:43:37.620 回答