Need to display in qtextEdit real time - qt

I have an arm board with a touchscreen display, where I want to display the output from a certain function, vcm_test(). The output of this function is saved to a file called
test.txt . Now I am able to read the contents of the file test.txt and display it in my qtextEdit only if it is less than 50-60 lines. Whereas I have more than 7000 lines in the test.txt . When I try to display 7000 lines the arm board keeps reading and nothing is displayed until reading is complete. Is there any way to read and display after every line or say every 10 lines. I thought of using qProcess in readfile too, but I have no idea how I can do that.
connect(ui->readfil, SIGNAL(clicked()), SLOT(readfile()));
connect(ui->VCMon, SIGNAL(clicked()), SLOT(vcm_test()));
connect(ui->Offloaderon, SIGNAL(clicked()), SLOT(offloader_test()));
connect(ui->quitVCM, SIGNAL(clicked()),vcmprocess, SLOT(kill()));
connect(ui->quitoffloader, SIGNAL(clicked()),offloaderprocess, SLOT(kill()));}
MainWindow::~MainWindow(){
delete ui;}
void MainWindow::readfile(){
QString filename="/ftest/test.txt";
QFile file(filename);
if(!file.exists()){
qDebug() << "NO file exists "<<filename;}
else{
qDebug() << filename<<" found...";}
QString line;
ui->textEdit->clear();
if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
QTextStream stream(&file);
while (!stream.atEnd()){
line = stream.readLine();
ui->textEdit->setText(ui->textEdit->toPlainText()+line+"\n");
qDebug() << "line: "<<line;}
}
file.close();}
void MainWindow::vcm_test(){
vcmprocess->start("/ftest/vcm_test_2");}
void MainWindow::offloader_test(){
offloaderprocess->start("/ftest/off_test_2");}
Any advice is really appreciated.Thanks.

You could use QApplication::processEvents() after reading every line and appending it to your text edit. But you should be really careful when using this, and I would not recommend doing so. You should also consider using QTextEdit::Append() instead of setText.
A better solution is to read the file in another thread and use signals and slots to send read data that you want to append to your QTextEdit.

Related

How to work around string splitting while loading a list from a file in QT

I'm trying to create a simple "To Do list" app in QT Creator while coding the part that loads and saves the list from a file I get stuck on a problem.
If you enter a string like "Do my homework" the program threads the string as it should, but when you load the program again the save file got split in words. So it gets all the entries but each word separated ("Do", "my", "homework").
What is the solution? I tried working with 'char arrays' and 'getline' but they give me nothing but errors.
Here is my code for the save and load parts:
void MainWindow::LoadList(){
std::ifstream load_file("./data.bin");
char loader[255];
while (load_file >> loader){
QString Writer = QString::fromStdString(loader);
ui->lstTaskList->addItem(Writer);
}
}
void MainWindow::SaveList(){
std::ofstream save_file("./data.bin");
for (auto i = 0; i < ui->lstTaskList->count(); i++){
QString Saver = ui->lstTaskList->item(i)->text();
std::string saver = Saver.toStdString();
save_file << saver << std::endl;
}
}
Can anyone help me with this, please?
My thanks in advance...
The anwser was using QFile and QByteArray for me, I knew about QFile but it tries using basic "std" c++ till I learned more about QT.

How to report progress without going through the entire file before I process

I have to parse a big file with several thousand records. I want to display a progress bar, but I do not know the number of recordings in advance. Do I have to roll over this file twice?
The first to know the number of recording.
The second to perform the treatment
Or is there a more simple way to get the number of records without going through the entire file before I process ?
My code snippet :
void readFromCSV(const QString &filename){
int line_count=0;
QString line;
QFile file(filename);
if(!file.open(QFile::ReadOnly | QFile::Text))
return;
QTextStream in(&file);
while(!in.atEnd()){ //First loop
line = in.readLine();
line_count++;
}
while (!in.atEnd()) { //Second loop
...
line = in.readLine();
process();
...
}
}
Thank you for help
This question is different from the one here : counting the number of lines in a text file
1) The loop process is already done. In this case it is prevention of double shooting.
2) The code is a QT one, not a C++ fonction to add as a redundancy
I think there is no way to count lines without reading the file at least once. To avoid it I wouldn't rely on the number of lines, but rather on how much data I have been read. Here is how I would solve this problem:
QFile file(fileName);
file.open(QFile::ReadOnly | QFile::Text);
const auto size = file.size();
QTextStream in(&file);
while (!in.atEnd()) {
auto line = in.readLine();
// Process line.
// [..]
// Calculate the progress in percent.
auto remains = file.bytesAvailable();
auto progress = ((size - remains) * 100) / size;
printf("progress: %d%%\r", progress);
}

QTextStream atEnd() is returning true when starting to read from a file

I want to read and parse contents of the /proc/PID/status file on a linux machine, but the QTextStream.atEnd is always returning true when starting to read. The code:
QString procDirectory = "/proc/";
procDirectory.append(QString::number(PID));
procDirectory.append("/status");
QFile inputFile(procDirectory);
if (inputFile.open(QIODevice::ReadOnly))
{
QTextStream in(&inputFile);
QString line;
while (!in.atEnd())
{
line = in.readLine();
File exists and if I read lines manually without the while expression, the files are read normally.
Did I miss something obvious?
(Debian 8 x64, QT 5.4.1 x64, gcc 4.9.2)
Nevermind found out I needed to read one line before the while clause, now it works.
The preferred way oft looping over these streams is with a do/while loop. This is for allowing the stream to detect Unicode correctly before any queries (like atEnd) are made.
QTextStream stream(stdin);
QString line;
do {
line = stream.readLine();
} while (!line.isNull());

Why QProcess signal readyReadStandardOutput() emited twice?

I use QProcess and connect it's readyReadStandardOutput to slot. But after starting slot execute twice. Tell me please why is it?
{
myProcess = new QProcess(parent);
myProcess->start("mayabatch.exe -file "+scene);
connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
}
void MainWindow::readOutput()
{
qDebug()<<"Read";
QByteArray outData = myProcess->readAllStandardOutput();
qDebug()<<QString(outData);
}
OUTPUT:
Read
"File read in 0 seconds.
"
Read
"cacheFi"
Read
"le -attachFile -fileName "nClothShape1" -directory ...
Last string was broken. "Read" appears between words.
From the documentation of QProcess::readyReadStandardOutput()
This signal is emitted when the process has made new data available through its standard output channel (stdout). It is emitted regardless of the current read channel.
The slot is executed more than once for the simple reason that the underlying process flushed the output in separate and random ways. You should not be caring about this because it depends on things you cannot control.
If you want to save the whole output you should be doing
void MainWindow::readOutput(){
bigbuffer.append(myProcess->readAllStandardOutput();)
}
If you want to read line by line, then
void MainWindow::readOutput(){
while(myProcess.canReadLine()){
qDebug() << myProcess.readLine();
}
}
The second call will leave data in the process buffer such that you don't have "broken" reads like cacheFi.

Overwrite text file vs append

I'm looking to overwrite data in a text file but all I can seem to do is append to it
mFile.open(QFile::ReadWrite)
QTextStream in(&mFile);
QString first = in.readLine(); //discard the headers
QString dataLine = in.readLine(); //headers
QStringList sql_row = dataLine.split("\t"); //first row (sake of proj only 1 row)
if(sql_row[1].isEmpty()) //no user name registered
{
QByteArray user= getenv("USERNAME"); //for windows
if(user.isEmpty())
{
user = getenv("USER"); ///for MAc or Linux
}
dataLine = dataLine.insert(dataLine.indexOf("\t")+ 1,user);
in << first << endl << dataLine << endl;
mFile.flush();
mFile.close();
Change
mFile.open(QFile::ReadWrite);
to
mFile.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text);
The QIODevice vs QFile distinction isn't necessary, but I personally favor using the base class. The Truncate flag will overwrite (i.e., delete) an existing file.
Alternatively, you can follow the other suggestion and open your text file directly using one of QTextStream's constructors. The same QIODevice::OpenMode conventions apply. This only works if mFile is a FILE object and not a QFile, which isn't the case in your example.
A couple additional notes for beginners.
Related Note 1
You didn't ask about this, but I also added the QIODevice::Text flag to ensure that newline characters get translated to/from the local encoding (plain \n vs. \r\n) when you use endl.
A really common mistake is to use \r\n AND QIODevice::Text, which results in text files with double-returns \r\r\n on Windows. Just use QIODevice::Text when opening and simply \n or endl and you'll never have this problem.
Related Note 2
Using QTextStream::endl will automatically call flush() each time. If your loop is large, use "\n" instead to prevent a slowdown unless you actually need to flush every line. The stream will automatically write to disk as its buffer gets full, or when it's closed.
QFile::close() also calls flush(), which makes your mFile.flush() at the end redundant.
Use an overloaded constructor of QTextStream:
QTextStream in(&mFile, QIODevice::ReadWrite | QIODevice::Truncate);
The QIODevice::Truncate will remove all the previous content of the file, and QIODevice::ReadWrite will open it for read and write access.

Resources