Page 1 of 2 12 LastLast
Results 1 to 20 of 23

Thread: Run several external programs sequetialy usig QProcess while reading stdout?

  1. #1
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Run several external programs sequetialy usig QProcess while reading stdout?

    Hi,

    I need to run a series of external programs one after the other but getting the output for each program. I have the programs in a QStringList and I can run them in a separate thread sequentially using:

    Qt Code:
    1. m_process->execute(programName,params);
    To copy to clipboard, switch view to plain text mode 

    The problem is that if I wait until finished I get any output until the program finish and one of the programs outputs a progress percentage I need to capture.. But with waiting until finished I get the last percentage (100). However I have no idea how to control the sequential execution of programs without waiting til one is finished.

    Here is the code:
    Qt Code:
    1. gobletthread::gobletthread(QObject * parent):
    2. QThread(parent)
    3. {
    4.  
    5. }
    6.  
    7. void gobletthread::run()
    8. {
    9. qDebug() << "Start of Run";
    10. m_process = new QProcess();
    11. connect(m_process,SIGNAL(finished(int)),this,SLOT(programExited(int)));
    12. connect(m_process,SIGNAL(readyReadStandardOutput()),this,SLOT(readData()));
    13. m_process->setWorkingDirectory("/data/cquiros/projects/ILRI-MARIO/software/nile");
    14. int pos;
    15.  
    16. for (pos = 0; pos <= m_programs.count()-1;pos++)
    17. {
    18. m_programID = pos;
    19. //Run the program
    20. runProgram(m_programs[pos].description,m_programs[pos].name,m_programs[pos].params);
    21. }
    22.  
    23. qDebug() << "End of Run";
    24.  
    25. }
    26.  
    27. void gobletthread::runProgram(QString description,QString program, QStringList params)
    28. {
    29. QSettings settings("ILRI", "NILE");
    30. QString gobletPath = settings.value("GOBLETPath","").toString();
    31. QString programName;
    32. if (!gobletPath.isEmpty())
    33. {
    34. programName = gobletPath + "/" + program;
    35. qDebug() << "Runing:" << program;
    36. if (QFile::exists(programName))
    37. {
    38. if ((program == "goblet-importdataset") ||
    39. (program == "goblet-importshape"))
    40. catchSubprocess = true; //Both import programs generate progress report in the stdout
    41. else
    42. catchSubprocess = false;
    43. emit processing(description);
    44. m_process->execute(programName,params); //Executes the program waiting until finish
    45. }
    46. else
    47. {
    48. qDebug() << program << "Does not exists!!!";
    49. }
    50. }
    51. else
    52. {
    53. qDebug() << "Goblet path does not exists";
    54. }
    55. }
    56.  
    57. void gobletthread::setPrograms(QList<TprogramInfo> programs)
    58. {
    59. m_programs.append(programs);
    60. }
    61.  
    62. void gobletthread::programExited(int exitCode)
    63. {
    64. emit programFinished(m_programID,exitCode);
    65. }
    66.  
    67. void gobletthread::readData()
    68. {
    69. if (!catchSubprocess)
    70. {
    71. //Intents to capture the total output after the end of execution
    72. QString data(m_process->readAll());
    73. if (!data.isEmpty())
    74. emit readyRead(m_programID,data);
    75. }
    76. else
    77. {
    78. // Intents to capture the output each time the the program writes in the stdout
    79. // Here we try to get the percentage processed by the program
    80. QString data(m_process->readLine(14));
    81. qDebug() << data;
    82. data = data.replace("%","");
    83. data = data.replace("inserted","");
    84. data = data.simplified();
    85. int perc;
    86. perc = data.toInt();
    87. if (perc > 0)
    88. emit subprocess(perc);
    89. }
    90. }
    To copy to clipboard, switch view to plain text mode 
    Any idea is much appreciated.

    Thanks,
    Carlos.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    What do you need threads for?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Hi,

    I don't know....Is the idea that I had to not hang the GUI with the waiting ... How would it be a better way?

    Thanks in advance,
    Carlos.

  4. #4
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Qt Code:
    1. m_process->execute(programName,params); //Executes the program waiting until finish
    To copy to clipboard, switch view to plain text mode 

    I don't think that is right. A new process is started - that command does not wait until it is finished
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  5. #5
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    From the documentation:

    Execute(const QString & program, const QStringList & arguments)

    Starts the program program with the arguments arguments in a new process, waits for it to finish, and then returns the exit code of the process

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Quote Originally Posted by qlands View Post
    From the documentation:

    Execute(const QString & program, const QStringList & arguments)

    Starts the program program with the arguments arguments in a new process, waits for it to finish, and then returns the exit code of the process
    It also says it is a static method. Anyway, if you don't want to wait then don't use a function that waits. Use one that doesn't.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Ah, I just read the bit for the 1 argument method
    This is an overloaded function.

    Starts the program program in a new process. program is a single string of text containing both the program name and its arguments. The arguments are separated by one or more spaces.
    Anyway, as wysota says, just use start instead of execute for asynchronous launching
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  8. #8
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    You effectively want to run a shell script while maintaining UI responsiveness. Something along these lines:
    1. Implement some sort of queue to contain the list of commands to execute.
    2. Take the first item from the queue and QProcess::start() it.
    3. Use the QProcess::readyReadStandardOutput () and QProcess::readyReadStandardError() signals to pick up output as it arrives
    4. Use the QProcess::finished() signal to:
      • Handle any remaining output from the program
      • Detect normal exit and return to 2.
      • Detect error states and do something like stop processing the script


    There should be no threads, blocking calls, or unresponsive UI.

  9. #9
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    ok. I re-implement without a QThread but still readyReadStandardOutput() does not get emmited when a program writes in the stdout.

    Qt Code:
    1. gobletrunner::gobletrunner(QWidget *parent) :
    2. QDialog(parent),
    3. ui(new Ui::gobletrunner)
    4. {
    5. ui->setupUi(this);
    6. this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
    7.  
    8. //Creates the process and connects it
    9. m_process = new QProcess(this);
    10. connect(m_process,SIGNAL(finished(int)),this,SLOT(programFinished(int)));
    11. connect(m_process,SIGNAL(readyReadStandardOutput()),this,SLOT(readyRead()));
    12.  
    13. totalPrograms = 0;
    14. totalProcessed = 0;
    15. }
    16.  
    17. gobletrunner::~gobletrunner()
    18. {
    19. delete ui;
    20. }
    21.  
    22. void gobletrunner::on_pushButton_clicked()
    23. {
    24. qDebug() << "Start commands";
    25. ui->progressBar->setMaximum(totalPrograms);
    26. if (m_programs.count() > 0)
    27. {
    28. processCommand(0); //Process the first program
    29. }
    30. else
    31. {
    32. close();
    33. }
    34. }
    35.  
    36. void gobletrunner::processCommand(int pos)
    37. {
    38. currProgram = pos;
    39. QSettings settings("ILRI", "NILE");
    40. QString gobletPath = settings.value("GOBLETPath","").toString();
    41. QString program;
    42. if (!gobletPath.isEmpty())
    43. {
    44. program = gobletPath + "/" + m_programs[pos].name;
    45. qDebug() << "Runing:" << m_programs[pos].name;
    46. if (QFile::exists(program))
    47. {
    48. ui->lblproc->setText(m_programs[pos].description + ". Please wait...");
    49. m_process->start(program,m_programs[pos].params); //Starts the program
    50. }
    51. else
    52. {
    53. if (currProgram +1 <= m_programs.count()-1)
    54. {
    55. processCommand(currProgram +1);
    56. }
    57. else
    58. {
    59. commandsFinished();
    60. }
    61. }
    62. }
    63. else
    64. {
    65. if (currProgram +1 <= m_programs.count()-1)
    66. {
    67. processCommand(currProgram +1);
    68. }
    69. else
    70. {
    71. commandsFinished();
    72. }
    73. }
    74. }
    75.  
    76.  
    77. void gobletrunner::programFinished(int exitCode)
    78. {
    79. totalProcessed++;
    80. ui->progressBar->setValue(totalProcessed);
    81. m_programs[currProgram].finished = true;
    82. m_programs[currProgram].exitcode = exitCode;
    83. QString data(m_process->readAll());
    84. m_programs[currProgram].output = data;
    85. if (currProgram +1 <= m_programs.count()-1) //If I have more programs
    86. {
    87. processCommand(currProgram +1);
    88. }
    89. else
    90. {
    91. commandsFinished();
    92. }
    93. }
    94.  
    95. void gobletrunner::readyRead()
    96. {
    97. qDebug() << "Ready to read";
    98.  
    99. //Both imports produce a percentage in the stdout
    100. if ((m_programs[currProgram].name == "goblet-importdataset") ||
    101. (m_programs[currProgram].name == "goblet-importshape"))
    102. {
    103. //Gets the data from the stdout and only grabs the percentage
    104. QString data(m_process->readLine(14));
    105. qDebug() << data;
    106. data = data.replace("%","");
    107. data = data.replace("inserted","");
    108. data = data.simplified();
    109. int perc;
    110. perc = data.toInt();
    111. if (perc > 0)
    112. ui->progressBar_2->setValue(perc);
    113. }
    114. }
    115.  
    116. void gobletrunner::commandsFinished()
    117. {
    118. close();
    119. }
    To copy to clipboard, switch view to plain text mode 

    But still the signal readyReadStandardOutput() does not get emmited when an import program writes a line in the stdout. This is what is written by the import programs:

    Qt Code:
    1. 29 % inserted
    2. 56 % inserted
    3. 86 % inserted
    4. 100 % inserted
    5.  
    6. Upload finished. 2072200 cells imported.
    7. Finished in 0 Hours,0 Minutes and 33 Seconds.
    To copy to clipboard, switch view to plain text mode 

    However I only get such result when the program finish.

    Any idea is much appreciated.

  10. #10
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Are you sure the data is on standard out and not error out? Have you tried to read the error channel as well?
    Have you checked that the signal/slot connection is made ok?
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  11. #11
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Hi,

    I added:

    m_process->setProcessChannelMode(QProcess::MergedChannels) ;

    So I merge the channels. The import programs the I am running uses printf for example: printf("%i %% inserted \n",perc);

    QT does not give me any warnings when I connect the signal.

    Still... the signal readyReadStandardOutput is not emmited when the import program writes to the stdout.

    Thanks,
    Carlos.

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    How do you know the signal is not emitted? Why are you calling readLine(14)?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #13
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Hi,

    Because that signal is connected to the slot readData() line 11. In readData() I have a qDebug() << "Ready to read"; in line 97 so I know that such slot is executed when the signal is emitted. If the import program writes 4 time or more I would expect 4 or more ""Ready to read" messages... But I Just get one "Ready to read" message once the program is finish

    I have readLine(14) to I just read 14 bytes.

    Thanks.

  14. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Quote Originally Posted by qlands View Post
    I have readLine(14) to I just read 14 bytes.
    And what do you intend to do with the rest of the line? Also does the slave program do any line buffering of its output? Does your code work with a different slave program?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  15. #15
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    I don't need the rest of the line. In fact the import programs produce a max of 14 bytes for reporting the progress. But the main problem is that such readline is not executed because the signal is not emmited!

    Only two programs report progress. I can try with other linux command programs to see if the signal gets emmited... but the import programs are nothing special.. just write in the stdout using printf()

    Thanks,
    Carlos.

  16. #16
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    once you have started a process, does control get back to the event loop before the process finishes?


    e: hmmm, looks like it does.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  17. #17
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    ok. I tried with a another program (a java that generates a lot of stdout) and the signal is emmited properly every time the program writes in the stdout. So there is somethig wrong with the import programs. Both import programs when ran get really busy inserting data into a mysql database but I can see in my terminal that they report the status. Is there anything else that I need to do besides a printf()? like refresing the stdout or something?

  18. #18
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    Quote Originally Posted by qlands View Post
    I don't need the rest of the line. In fact the import programs produce a max of 14 bytes for reporting the progress.
    So read the whole line and then discard whatever you don't need. If you only read 14 bytes then next time you call readLine(14), you'll get next (up to) 14 bytes of the first line. That's probably not what you want.

    Is there anything else that I need to do besides a printf()? like refresing the stdout or something?
    You need to write the end of line character and/or fflush stdout.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  19. The following user says thank you to wysota for this useful post:

    qlands (13th July 2012)

  20. #19
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    writing '\n' doesn't guarantee a flush, but std::endl does, or so I have read. That must be for cout rather than printf, though. Although why use printf in the first place?
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  21. The following user says thank you to amleto for this useful post:

    qlands (13th July 2012)

  22. #20
    Join Date
    Mar 2010
    Location
    Heredia, Costa Rica
    Posts
    257
    Thanks
    24
    Thanked 17 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Run several external programs sequetialy usig QProcess while reading stdout?

    I don't know why but this line

    Qt Code:
    1. printf("\r%i %% inserted", perc);
    To copy to clipboard, switch view to plain text mode 

    Was working properly the last time I run the program.. Not is does not print in the terminal and I just get the final percentage (100)..... the line gets executed in between heavy inserts to a mysql database... so maybe the stdout is not refreshed in time.

    What else can I use besides printf()?

    Thanks,


    Added after 13 minutes:


    Ha!!! If I change the printf for a qDebug() the signal is emmited and all works fine!.... very interesting!
    Last edited by qlands; 13th July 2012 at 14:02.

Similar Threads

  1. Calling external programs via QProcess on Mac OS
    By berliner in forum Qt Programming
    Replies: 13
    Last Post: 15th December 2014, 21:35
  2. Using the Stdout reading in QProcess
    By DiegoTc in forum Newbie
    Replies: 12
    Last Post: 10th July 2011, 07:36
  3. Replies: 3
    Last Post: 19th March 2011, 05:02
  4. Using the Stdout reading in QProcess
    By DiegoTc in forum Qt Programming
    Replies: 7
    Last Post: 29th December 2010, 14:34
  5. QProcess & Working with External Programs
    By jstippey in forum Qt Programming
    Replies: 2
    Last Post: 20th December 2010, 20:04

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.