2017-06-02 232 views
0

我正在嘗試將要顯示的文本文件的內容傳輸到我的GUI中的textEdit小部件。Qt:在特定時間間隔內逐行讀取文本文件

我該如何讓它在文本上一次顯示一行,而不是一次性顯示文本文件的所有內容到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編程,所以請溫柔給我~~ ^^

+0

向我們展示使用'readLine'讀取文件的代碼。我想你在調用'readLine'之後關閉了流,因此每次執行代碼時,它總是從第一行開始。相反,你不應該在達到'EOF'之前關閉流。 – putu

+0

void ReadTextFile :: on_pushButton_4_clicked() QFile textfile(「my_file_here」); (textfile.open(QIODevice :: ReadOnly)|| QIODevice :: Text) { QTextStream in(&textfile); (!in.atEnd()) QString line = in.readLine(); ui-> textEdit-> append(line); } textfile.close(); qDebug()<<「關閉文本文件」; } qDebug()<<「Out Pushbutton File」; } –

+0

對不起,我不知道如何使用插入編碼像你的 –

回答

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顯示的文本,我們需要的原料線轉換成字符串。

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" 

這結束了完整的例子,因爲QPlainTextEdit::appendPlainText已經增加了一個段落的結束,我們必須刪除任何行結尾。

+0

謝謝,先生!我已經運行該程序並運行良好。 但是對於我來說,代碼有點難以理解,特別是在main.cpp文件的第16,17,33行和從第47行到第56行。但感謝您的幫助! ^^ –

+0

這是2017年,所以我們應該使用現代C++ 11。似乎你沒有跟上它。 ** 16 **'{}'提供了一個默認構造的值,而指針與'nullptr'相同。在過去,你會寫'0'或'NULL'。 ** 17 **這是現代連接語法。參見Qt文檔。 ** 33 **我們從UTF8表示中創建一個字符串。一個文件本身沒有意義,所以我們將一串字節轉換爲一個字符串。 ** 47-56 **我們將點擊的信號連接到一個lambda - 一個延續對象,它捕獲對周圍環境的引用。蘭巴達斯帶回帕斯卡爾地方功能,並增壓他們:) –

+0

謝謝,@ KubaOber。 我想知道是否可以根據文本文件的順序將逐行讀取的文本行作爲輸入插入到Arduino中? –

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

+0

謝謝@ eyllanesc,我已經試過你的代碼,但是當我試圖運行該程序就說明 錯誤「過客‘常量QStringList中’爲‘本’的說法丟棄預選賽[-fpermissive]」 在行 「texts.pop_front();」 我在哪裏做錯了? –

+0

我已經通過鏈接到整個項目,運行它,並告訴我你得到什麼,請。 – eyllanesc

+0

我有一些用戶界面文件的問題。當我雙擊Qt創建者內部的ui文件來訪問它時,會顯示一個對話框。 「 」在讀取第35行第98列的UI文件時發生了錯誤:預期'=',但得到了'>'。「 –