Russian Qt Forum

Qt => Общие вопросы => Тема начата: #pragma от Ноябрь 29, 2009, 07:23



Название: [Решено]Прочитать вывод программы,запускаемой с помощью QProcess.
Отправлено: #pragma от Ноябрь 29, 2009, 07:23
Нужно запустить внешнюю программу из графического интерфейса с помощью QProcess,и прочитать из стандартного потока ошибок,что пишет программа,и как-то "положить" эти строки с ошибками в QListWidget или в QTextEdit.Как это сделать (на примере?). Я пытался по всякому,но не получилось.
Код
C++ (Qt)
   console = new QProcess;
   console->setReadChannel (QProcess::StandardError);
   QByteArray arr;
   /*if (!console->startDetached("/usr/bin/xterm",QStringList()<< "-e"
                                                             << "./myprogram"
                                                             << *args
                                                             << filename))*/

 
   if (!console->execute ("./myprogram",QStringList() << *args << filename))
   {
   }
   arr = console->readAllStandardOutput();
   std::cout << arr.data();
   //  editor объявлен как QTextEdit *editor;
   editor ->insertPlainText( arr.data() );
Почему-то переменная arr остаётся пустой.


Название: Re: Прочитать вывод программы,запускаемой с помощью QProcess,которая пишет в stdout.
Отправлено: Rcus от Ноябрь 29, 2009, 08:22
execute - статический метод класса QProcess. Используйте QProcess::start(), QProcess:waitForFinished() если время исполнения достаточно мало.


Название: Re: Прочитать вывод программы,запускаемой с помощью QProcess,которая пишет в stdout.
Отправлено: #pragma от Ноябрь 29, 2009, 10:04
Да я всё перепробовал,и start,и startDetached,и ведь дело не в том,что я не успеваю прочитать ошибку )) Я специально её генерирую и мне нужно,чтобы строка с ошибкой отобразилась в QTextEdit,хотя бы просто в переменную записать,там уже проще. Вот это как сделать?


Название: Re: Прочитать вывод программы,запускаемой с помощью QProcess,которая пишет в stdout.
Отправлено: spectre71 от Ноябрь 29, 2009, 12:05
Нужно запустить внешнюю программу из графического интерфейса с помощью QProcess,и прочитать из стандартного потока ошибок,что пишет программа,и как-то "положить" эти строки с ошибками в QListWidget или в QTextEdit.Как это сделать (на примере?). Я пытался по всякому,но не получилось.
Код
C++ (Qt)
   console = new QProcess;
   console->setReadChannel (QProcess::StandardError);
   QByteArray arr;
   /*if (!console->startDetached("/usr/bin/xterm",QStringList()<< "-e"
                                                             << "./myprogram"
                                                             << *args
                                                             << filename))*/

 
   if (!console->execute ("./myprogram",QStringList() << *args << filename))
   {
   }
   arr = console->readAllStandardOutput();
   std::cout << arr.data();
   editor ->insertPlainText( arr.data() );
Почему-то переменная arr остаётся пустой.

Цитировать
QByteArray QProcess::readAllStandardError ()

Regardless of the current read channel, this function returns all data available from the standard error of the process as a QByteArray.

Естественно. Ты создаешь процесс, а далее вызываешь readAllStandardError! А процесс еще ничего не вывел, вот тебе и пустые данные. А даже если бы и успел вывесит то только часть. методы readAllStandardOutput и readAllStandardError не делают ожидание завершение вывода данных, и не должны этого делать, они отдают то что накопилось к моменту их вызова.

Воспользуйся сигналами:
void QProcess::readyReadStandardError ()
void QProcess::readyReadStandardOutput ()


Название: Re: Прочитать вывод программы,запускаемой с помощью QProcess,которая пишет в stdout.
Отправлено: #pragma от Ноябрь 30, 2009, 02:49
Естественно. Ты создаешь процесс, а далее вызываешь readAllStandardError! А процесс еще ничего не вывел, вот тебе и пустые данные.
А разве эта строка
Код
C++ (Qt)
   if (!console->execute ("./myprogram",QStringList() << *args << filename))
только создаёт процесс? Я думал,процесс отрабатывает с нужными параметрами и только потом (когда stderr уже получил данные об ошибке,происходит попытка чтения
Код
C++ (Qt)
arr = console->readAllStandardOutput();
Разве это не так?
Воспользуйся сигналами:
void QProcess::readyReadStandardError ()
void QProcess::readyReadStandardOutput ()
А можно пример небольшой,как правильно эти сигналы использовать,дело в том,что я только-только начал знакомство с Qt,да и программировать только учусь. Я вот так ошибочно пробовал связать сигнал и нужную функцию:
Код
C++ (Qt)
/* -------------------------------------------------------------------------- */
 void MainWindow::readErr()
 {
    arr = new QByteArray;
    *arr = console->readAllStandardError();
 }
/* -------------------------------------------------------------------------- */
 void MainWindow::run()
 {
   console = new QProcess;
   console->setReadChannel (QProcess::StandardError);
   console->start("./myprogram",QStringList() << *args << filename);
   connect(console, SIGNAL(readyReadStandardError()), this, SLOT(readErr()));
   std::cout << arr->data();
   editor ->insertPlainText( arr->data() );
   ...
/* -------------------------------------------------------------------------- */
Но прога красиво вылетела в Seg.Fault. Можете хотя бы примерно показать,как нужно сделать в этом случае?


Название: Re: Прочитать вывод программы,запускаемой с помощью QProcess,которая пишет в stdout.
Отправлено: SimpleSunny от Ноябрь 30, 2009, 03:01
То что программа вывалилась в сегфаулт правильно, ведь на момент записи, arg  мог быть еще не создан.

надо примерно так.
Код:

  void MainWindow::finished()
  {
     arr = new QByteArray;
     *arr = console->readAllStandardError();
    std::cout << arr->data();
    editor ->insertPlainText( arr->data() );
  }

  void MainWindow::run()
  {
    console = new QProcess;
    connect(console, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished()));
    console->setReadChannel (QProcess::StandardError);
    console->start("./basin",QStringList() << *args << filename);
    }


Название: Re: Прочитать вывод программы,запускаемой с помощью QProcess,которая пишет в stdout.
Отправлено: #pragma от Ноябрь 30, 2009, 03:29
Ура! Получилось  :) Спасибо большое,хоть немного проясняется.