Qt:在特定时间间隔内逐行读取文本文件

时间:2017-06-02 02:04:56

标签: qt qt5 readline qtextedit qtextstream

我正在尝试将要显示的文本文件的内容传输到GUI中的textEdit小部件。

如何在文本中一次显示一行显示,而不是一次将文本文件的所有内容显示到textEdit小部件中?

通过使用“readLine”,它只能显示文本文件内容的第一行。如何让它显示内容的第二行,比方说2秒?

以下是我的代码示例:

void ReadTextFile::on_pushButton_4_clicked() 
QFile textfile("my_file_here"); 
if (textfile.open(QIODevice::ReadOnly)||QIODevice::Text) { 
QTextStream in(&textfile); 
while (!in.atEnd()) { 
QString line = in.readLine(); 
ui->textEdit->append(line); 
} 
textfile.close();
 qDebug() <<"Close Text File"; 
} 
qDebug() <<"Out Pushbutton File"; 
}

我是一个学习Qt编程的新人,所以请对我温柔~~ ^^

2 个答案:

答案 0 :(得分:1)

您必须创建QTimer以每2秒运行一次任务。要处理文本,您可以创建QStringList,其中每行添加readLine()atEnd函数将指示文件中有偶数数据。

QStringList texts;

QTimer *timer = new QTimer(this);

connect(timer, &QTimer::timeout, [=](){
    if(!texts.isEmpty()){
        your_textEdit->append(texts.first());
        texts.pop_front();
    }
    else
        timer->stop();
});

QString fileName = "path_of_your_file"
QFile file(fileName);
if(file.open(QIODevice::ReadOnly)) {
    QTextStream in(&file);
    while (!in.atEnd()) {
        texts.append(in.readLine());
    }
    timer->start(2000);
}
file.close();

完整代码为here

答案 1 :(得分:1)

您可以使用计时器来触发连续行的读取。此功能最好分为自己的类,每次有新行时都会发出信号:

// https://github.com/KubaO/stackoverflown/tree/master/questions/timed-read-44319722
#include <QtWidgets>

class PeriodicReader : public QObject {
   Q_OBJECT
   QTimer m_timer{this};
   QFile m_file{this};
   void readLine() {
      if (m_file.atEnd()) {
         m_timer.stop();
         return;
      }
      emit newLine(m_file.readLine());
   }
public:
   explicit PeriodicReader(QObject * parent = {}) : QObject(parent) {
      connect(&m_timer, &QTimer::timeout, this, &PeriodicReader::readLine);
   }
   void load(const QString & fileName) {
      m_file.close(); // allow re-opening of the file
      m_file.setFileName(fileName);
      if (m_file.open(QFile::ReadOnly | QFile::Text)) {
         readLine();
         m_timer.start(300); // 0.3s interval
      }
   }
   Q_SIGNAL void newLine(const QByteArray &);
};

由于我们使用QPlainTextEdit来显示文本,我们需要将原始行转换为字符串。我们必须删除任何行结尾,因为QPlainTextEdit::appendPlainText已经添加了段落结尾:

QString lineToString(QByteArray line) {
   while (line.endsWith('\n') || line.endsWith('\r'))
      line.chop(1);
   return QString::fromUtf8(line);
}

将它组合成一个演示现在是一件简单的事情:

int main(int argc, char ** argv) {
   QApplication app{argc, argv};

   QWidget window;
   QVBoxLayout layout{&window};
   QPushButton load{"Load"};
   QPlainTextEdit edit;
   layout.addWidget(&load);
   layout.addWidget(&edit);
   window.show();

   PeriodicReader reader;
   QObject::connect(&load, &QPushButton::clicked, [&]{
      auto name = QFileDialog::getOpenFileName(&window);
      if (!name.isEmpty()) {
         edit.clear(); // allow re-opening of the file
         reader.load(name);
      }
   });
   QObject::connect(&reader, &PeriodicReader::newLine, &edit,
                    [&](const QByteArray & line){ edit.appendPlainText(lineToString(line)); });

   return app.exec();
}
#include "main.moc"

这是完整的例子。