QTextStream read issue



  • Hi! I want to read some text from file and display in QPlainTextEdit. File is about 2 MB. I have created QObject class and connect signals and slots with thread. The problem is it still freezes window even when the thread is running.

    I have decided to use QtConcurrent.

    My code:

    QFile dbFile;
    QTextStream dbTextStream;
    dbFile.setFileName(":Test/Test.txt");
    dbFile.open(QIODevice::ReadOnly);
    dbTextStream.setDevice(&dbFile);
    dbTextStream.setCodec("windows-1251");
    QFuture<QString> myData = QtConcurrent::run(this, &TestWindow::loadTestData);
    ui->plainTextEdit->appendPlainText(myData.result());
    
    QString TestWindow::loadTestData()
    {
      QString data = dbTextStream.readAll();
      return data;
    }
    

    No errors, no warnings but it blocks window (GUI) for seconds.

    So I have to use QFutureWatcher:

    QFutureWatcher<QString> watcher;
     connect(&watcher, QFutureWatcher::finished, this, &TestWindow::handleFinished);
    
    QFuture<QString> myData = QtConcurrent::run(this, &TestWindow::loadDatabase);
    watcher.setFuture(myData);
    
    void DatabaseManager::handleFinished()
    {
        // Append text data to QPlainTextEdit
    }
    

    When I compile it throws errors: C2955: 'QFutureWatcher': use of class template requires template argument list 'QFutureWatcherBase::finished': non-standard syntax; use '&' to create a pointer to member

    So how to fix it?


  • Lifetime Qt Champion

    Hi,

    I'd avoid emitting 2MB of text at once.

    Note that your while loop will only run once since you call readAll in it.



  • @SGaist

    I have used readLine but it displays only one line?


  • Lifetime Qt Champion

    Because you call emit testData outside of the loop thus only sending the last line read.



  • @SGaist

    I changed code to:

    while (!dbTextStream.atEnd()) {
            data = dbTextStream.readLine();
            emit databaseData(data);
        }
    

    But window is still not responding and after a while displays only one line?


  • Lifetime Qt Champion

    Are you calling setText rather than append ?

    Be aware that with such a loop you are basically spamming the event loop that will try to re-render the text widget content for each new line you read. You should rather use batches and give the event loop some time to work.



  • @SGaist

    Yes. The problem was that I use setText rather than append and now it sets all text, but still window not responding. What do you mean about using batches?


  • Lifetime Qt Champion

    I don't know how many lines your text file contains but basically you are likely requesting tens of thousands of line to be added in a fraction of a second.

    Doing batches means doing things by chunks i.e. load a certain amount of data, send it further and start again until everything has been read..



  • @SGaist

    Yes. The file contains a lot of lines.
    But why QThread can't handle it? I have the same program written in C# and it opens and displays one file without dividing it by chunks. Are there other classes in Qt to read huge text files?



  • The main post was updated to display current issue.


  • Lifetime Qt Champion

    As the error mention, you forgot to put the & and the template type. i.e. &QFutureWatcher<int>::finished


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.