Unsolved QTextStream read issue
-
Hi! I want to read some text from file and display in
QPlainTextEdit
. File is about 2 MB. I have createdQObject
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?
-
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. -
I have used
readLine
but it displays only one line? -
Because you call
emit testData
outside of the loop thus only sending the last line read. -
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?
-
Are you calling
setText
rather thanappend
?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.
-
Yes. The problem was that I use
setText
rather thanappend
and now it sets all text, but still window not responding. What do you mean about using batches? -
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..
-
Yes. The file contains a lot of lines.
But whyQThread
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.
-
As the error mention, you forgot to put the
&
and the template type. i.e.&QFutureWatcher<int>::finished