PDA

View Full Version : readLine in QProcess



grisson
14th October 2009, 15:59
Hi to all.
I'm developing a small program that get some info from a command line tool (clt) and elaborate it.

I'm using QProcess to start the clt and the signal readyReadStandardOutput() to execute the functin that read the std out of the clt.

it works but don't read the last line.

For example, if the clt write to out:

first pass ok
second pass ok
third pass failed
4th pass ok
5th pass failed

and the gui slot connected to readyReadStandardOutput is

f(){
QString strOut=Process->readLine();
QMessageBox::information(this,"aaa",strOut);
}

the program show only 4 pupups with the first 4 lines(the popup with "5th pass failed" is not showed) .
sometimes, there is a pause of 3-4 seconds between various output lines from the clt because some times it use the network to do the job.

i'm doing someting wrong?

Thanks for help:), and sorry for english:o...


EDIT: using qt 4.5.2 on windows xp

high_flyer
14th October 2009, 20:37
Can you show a bit more of your code, in particular, when and how you are destroying you QProcess object?
It could be you are destroying your QProcess object before it got a chance to send the readyReadStandardOutput() signal.

grisson
14th October 2009, 21:26
here it is the code of the click slot of one button:



void MainJackSMS::on_InviaSMS_clicked(){
SendSmsProcess = new QProcess( this );
QStringList arguments;
arguments <<"-sms64"<<_smsText<<"-dest"<<_dest;
arguments <<"-serv"<<_serv;
connect(SendSmsProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(ReadStdoutSendSms()));
SendSmsProcess->start(JACKSMS_BINARY_FILENAME,arguments);
}

(note: _smsText, _serv and _dest are results of some omitted functions)

SendSmsProcess is declared in the declaration of the class ( into the header file)


private:
QProcess *SendSmsProcess;


the object pointed from SendSmsProcess is destroyed when the program is closed(actually for some test i don't destroy the object). it can be a problem?



EDIT: during some tests today, i've writthen another line (now are 6 lines) from the clt to stdout and the qt gui has readed all the lines except the 6th line. afther that i've printed out with a loop 100 lines, but only 99 lines are readed from the gui. the problem is always the same.:(

high_flyer
15th October 2009, 10:45
You are allocating a new QProcess every time on_InviaSMS_clicked() is being called, without destroying it afterwords - not good - your this is a memory leak.
The best would be to initialize it once and start and close new process on the same object.
Or, if you want to allocate a new object every time you need to delete it when you don't need it anymore.
But I don't think this has to do with your problem.

What happens if you add a '\n' to the last string you send?

grisson
15th October 2009, 17:14
What happens if you add a '\n' to the last string you send?

nothing, all the strings are already sended with the '\n' char...

i've tried another way.
i've edited the ReadStdoutSendSms() functions.
now is like this:


ReadStdoutSendSms(){

for (int i=0;i<5;i++){
if (Process->canReadLine()){
QString strOut=Process->readLine();
QMessageBox::information(this,"aaa",strOut)
}else{
Sleep(10); //defined in windows.h

}
}


Works , but (obviously) it freeze the gui. i can try to do this in a different thread, , however i don't think it is a good solution...

high_flyer
15th October 2009, 18:11
oh wait, so the original code was sending the 5 strings, and then what?
Did the application end?
If yes, then my original assumption (QProcess object being deleted before the it could read the cout) was *probably* correct.

It looks to be a very not efficient way of doing things in your code, but its hard to say exactly what would be a better waz with out seeing more of it.

You can have the gui responsive in your new code by adding QApplication::processEvents() in your loop.

grisson
15th October 2009, 18:34
oh wait, so the original code was sending the 5 strings, and then what?
Did the application end?
If yes, then my original assumption (QProcess object being deleted before the it could read the cout) was *probably* correct.

It looks to be a very not efficient way of doing things in your code, but its hard to say exactly what would be a better waz with out seeing more of it.

You can have the gui responsive in your new code by adding QApplication::processEvents() in your loop.

no.the original tool send an arbitrary number of lines. for a test i have limited the numer to 5 but it can be 1,2,3 or 10,20 etc... and after it sent the last line, the program terminate immediatly(and for this, your assumption seem to be plausible).

the previous code was only a test to see if the gui receive all the lines.

high_flyer
15th October 2009, 18:39
Well yes, if your application terminates immediately after sending the last string, then I strongly suspect it terminates before QProcess had a change to handle the last slot.

Try to have the application not terminate, and see if this solves the problem.
If you get all the strings when the application doesn't terminate, then you have a design problem.