2017-06-02 1 views
0

Ich versuche, den Inhalt einer anzuzeigenden Textdatei auf das TextEdit Widget in meiner GUI zu übertragen.Qt: Lies eine Textdatei Zeile für Zeile in einem bestimmten Zeitintervall

Wie kann ich es im Text anzeigen lassen, bearbeiten Sie Zeile für Zeile, anstatt den gesamten Inhalt der Textdatei gleichzeitig im TextEdit-Widget anzuzeigen?

Mit "readLine" kann nur die erste Zeile des Inhalts der Textdatei angezeigt werden. Wie kann ich die zweite Zeile des Inhalts nach, sagen wir 2 Sekunden?

Hier ist die Probe meiner Code:

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"; 
} 

Ich bin ein neuer Typ Qt-Programmierung zu lernen, so wenden Sie sich bitte an mich sanft ~~ ^^

+0

Zeigen Sie uns den Code, der die Datei mit 'readLine' liest. Ich denke, Sie schließen den Stream nach dem Aufruf von 'readLine', also jedes Mal, wenn dieser Code ausgeführt wird, beginnt er immer in der ersten Zeile. Stattdessen sollten Sie den Stream nicht schließen, bevor Sie 'EOF' erreichen. – putu

+0

void ReadTextFile :: on_pushButton_4_clicked() QFile Textdatei ("my_file_here"); if (textdatei.open (QIODevice :: ReadOnly) || QIODevice :: Text) { QTextStream in (& textfile); während (! In.atEnd()) { QString line = in.readLine(); ui-> TextEdit-> Anhängen (Linie); } textdatei.close(); qDebug() << "Textdatei schließen"; } qDebug() << "Drucktaste Datei"; } –

+0

Entschuldigung, ich weiß nicht, wie Insert-Codierung wie Sie verwenden –

Antwort

1

Sie können einen Timer verwenden, um das Lesen aufeinanderfolgender Zeilen auszulösen. Diese Funktionalität wird am besten in seine eigene Klasse getrennt, die ein Signal jedesmal, wenn eine neue Zeile emittiert verfügbar:

// 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 &); 
}; 

Da wir eine QPlainTextEdit verwenden um den Text anzuzeigen, müssen wir die Rohzeilen in Strings konvertieren. Wir müssen alle Zeilenenden entfernen, da QPlainTextEdit::appendPlainText bereits einen Absatz Ende fügt hinzu:

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

Es ist jetzt eine einfache Sache, um es zusammen in eine Demo:

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" 

Dies schließt die vollständige Beispiel.

+0

Danke, mein Herr! Ich habe das Programm ausgeführt und funktioniert gut. Aber der Code ist ein bisschen schwierig zu verstehen, vor allem in Zeile 16,17,33 und von 47 bis 56 der main.cpp Datei. Aber danke für die Hilfe! ^^ –

+0

Es ist 2017, also sollten wir moderne C++ 11 verwenden. Scheint, du hast damit nicht Schritt gehalten. ** 16 ** '{}' liefert einen standardkonstruierten Wert, und für Zeiger ist das gleiche wie 'nullptr'. Früher würden Sie '0' oder' NULL' schreiben. ** 17 ** Dies ist die moderne Verbindungssyntax. Siehe Qt Dokumentation. ** 33 ** Wir erstellen eine Zeichenfolge aus UTF8-Darstellung. Eine Datei selbst hat keine Bedeutung, daher konvertieren wir einen Datenstrom in eine Zeichenfolge. ** 47-56 ** Wir verbinden das angeklickte Signal mit einem Lambda - einem Fortsetzungsobjekt, das Verweise auf den umgebenden Kontext erfasst. Lambdas bringen die lokalen Pascal-Funktionen zurück und laden sie auf :) –

+0

danke, @KubaOber. Ich frage mich, ob die Textzeile, die Zeile für Zeile gelesen wird, kann in Arduino als Eingabe entsprechend der Sequenz aus der Textdatei eingefügt werden? –

1

Sie eine QTimer erstellen müssen die Aufgabe ausgeführt werden soll alle 2 Sekunden. Um den Text zu bearbeiten, können Sie einen erstellen, in dem Sie jede Zeile mit readLine() hinzufügen, die atEnd-Funktion zeigt an, dass es sogar Daten in der Datei gibt.

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(); 

Der vollständige Code ist here.

+0

Danke @ eyllanesc, ich habe Ihren Code versucht, aber als ich versuchte, das Programm zeigt es einen Fehler von „passing‚const QStringList‘als‚das‘Argument verwirft Qualifikation [-fpermissive]“ auf Linie laufen "texts.pop_front();" Wo habe ich falsch gemacht? –

+0

Ich habe den Link zum gesamten Projekt übergeben, führe es aus und sag mir, was du bekommst, bitte. – eyllanesc

+0

Ich habe ein Problem mit der UI-Datei. Als ich zweimal auf die ui-Datei im Qt-Ersteller klickte, um darauf zuzugreifen, wurde ein Dialogfeld angezeigt. "Beim Lesen der UI-Datei in Zeile 35, Spalte 98 ist ein Fehler aufgetreten: Erwartet '=', aber '>'." –

Verwandte Themen