Qt:在特定时间间隔逐行读取文本文件
Qt : Read a text file line by line in a specific time interval
我正在尝试将要显示的文本文件的内容传输到我的 GUI 中的文本编辑小部件。
如何让它在文本编辑中一次显示一行,而不是一次将文本文件的所有内容显示到文本编辑小部件中?
使用"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 秒创建一个 QTimer
到 运行 任务。要处理文本,您可以创建一个 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.
您可以使用计时器触发连续行的读取。这个功能最好分成它自己的 class,每次有新行可用时它都会发出一个信号:
// https://github.com/KubaO/Whosebugn/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"
完整示例到此结束。
我正在尝试将要显示的文本文件的内容传输到我的 GUI 中的文本编辑小部件。
如何让它在文本编辑中一次显示一行,而不是一次将文本文件的所有内容显示到文本编辑小部件中?
使用"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 秒创建一个 QTimer
到 运行 任务。要处理文本,您可以创建一个 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.
您可以使用计时器触发连续行的读取。这个功能最好分成它自己的 class,每次有新行可用时它都会发出一个信号:
// https://github.com/KubaO/Whosebugn/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"
完整示例到此结束。