Russian Qt Forum

Qt => Работа с сетью => Тема начата: Az от Апрель 18, 2010, 00:31



Название: Command output in "real time'
Отправлено: Az от Апрель 18, 2010, 00:31
Всем доброго времени суток.

Столкнуся с такой проблемой - вывод некоторых команд-а в textedit. Задачка довольно тривиальная, решение нашел, но есть одно но:

Код
C++ (Qt)
QString program;
QStringList arguments;
program="traceroute";
arguments << "ya.ru";
QProcess myProcess;
myProcess.start(program, arguments);
myProcess.waitForFinished();
myProcess.deleteLater();
ui->te->append( QString::fromLocal8Bit(myProcess.readAllStandardOutput()));
ui->te->append( QString::fromLocal8Bit(myProcess.readAllStandardError()));
 

Он ждет, когда команда выводит результат, и только потом выводит его в textedit. Если, например, эта команда ping, то окно не появляется вообще.
Подскажите, пожалуйста, как можно сделать этот вывод в реальном времени?


Название: Re: Command output in "real time'
Отправлено: Пантер от Апрель 18, 2010, 09:48
void QProcess::readyReadStandardOutput ()   [signal]


Название: Re: Command output in "real time'
Отправлено: Az от Апрель 18, 2010, 12:40
Если я правильно понял, то должно быть что-то вроде:

Код
C++ (Qt)
  QProcess *term_command = new QProcess(this);
   connect(term_command, SIGNAL(readyReadStandardOutput()), SLOT(command_print()));
   term_command->start("ping", QStringList() << "192.168.1.1");
 
 
}
void MainWindow::command_print()
{
   QByteArray output = term_command->readAllStandardOutput();
   ui->textEdit->append(output.data());
}

но, что-то я все-таки неправильно делаю

отладчик ругается - error: base operand of ‘->’ has non-pointer type ‘QProcess’



UPD:
Переделал так:
Код
C++ (Qt)
void MainWindow::run()
{
   QProcess *term_command = new QProcess(this);
   connect(term_command, SIGNAL(readyReadStandardOutput()), SLOT(run()));
   term_command->start("ping", QStringList() << "192.168.1.1");
}
 
void MainWindow::finished()
{
 
 
 
 
   QByteArray result=term_command.readAllStandardOutput();
   QStringList lines = QString(result).split("\n");
   foreach (QString line, lines)
   {
        ui->textEdit->append(line);
    }
 
 
}

Но в выводе только пробелы, то бишь ничего...


Название: Re: Command output in "real time'
Отправлено: MoPDoBoPoT от Апрель 18, 2010, 14:12

...
QProcess *term_command= new QProcess(this);
connect(term_command, SIGNAL(readyReadStandardOutput()), SLOT(command_print()));
....
...
QByteArray result=term_command.readAllStandardOutput();
...
В конструкторе создаешь указатель на QProcess, конектишь его со слотом, а вслоте уже хочешь прочитать из объекта (другого QProcess) члена класса.
Надо как-то так:
Код
C++ (Qt)
class MainWindow : public QMainWindow
{
...
private:
   QProcess *term_command;
...
};
 
----
MainWindow::MainWindow(QWidget *parent /*=0*/) : QMainWindow(parent)
{
...
   term_command = new QProcess(this);
   term_command->setProcessChannelMode(QProcess::MergedChannels);
   connect(term_command, SIGNAL(readyReadStandardOutput()), SLOT(command_print()));
   term_command->start("ping", QStringList() << "192.168.1.1");    
...
}
 
void MainWindow::command_print()
{
   QByteArray output = term_command->readAllStandardOutput();
...
}
 


Название: Re: Command output in "real time'
Отправлено: Az от Апрель 18, 2010, 14:31
Мой косяк, однако.  setProcessChannelMode прохлопал  :-[

Спасибо, друг!  :)


Название: Re: Command output in "real time'
Отправлено: Az от Апрель 18, 2010, 21:06
Еще небольшой вопрос:
Как можно отправить этому процессу SIGINT (Crtl+C), чтобы был вывод результатов пинга, а не просто kill, когда процесс умирает молча?
Пробовал что-то типа:
Код
C++ (Qt)
...
connect(term_command, SIGNAL(processExited()), this, SLOT(exitProcess()));
...
void XDiagnosticTool::exitProcess()
{
 delete term_command;
 term_command = 0;
}

Но компилятор только выводит Object::connect: No such signal QProcess::processExited(), и вот почему его там no such, я пока не понял.


Название: Re: Command output in "real time'
Отправлено: BRE от Апрель 18, 2010, 22:19
Но компилятор только выводит Object::connect: No such signal QProcess::processExited(), и вот почему его там no such, я пока не понял.
А где ты в QProcess нашел сигнал processExited?

void QProcess::finished ( int exitCode, QProcess::ExitStatus exitStatus )   [signal]


Название: Re: Command output in "real time'
Отправлено: Az от Апрель 19, 2010, 00:34
А где ты в QProcess нашел сигнал processExited?

Хороший вопрос... Действительно, где я его там нашел...

Переделал под finished, но вместо ping-а завершается все приложение...

Код
C++ (Qt)
connect(term_command,SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(exitProcess()));
...
void XDiagnosticTool::exitProcess()
{
 delete term_command;
 term_command = 0;
}

Что-то не уловлю я принцип, получается, что при завершении должна выполнится ф-ция exitProcess(), но ее принудительный вызов и удаление переменной процесса походу ее просто крашит...
Если мысли не там, где должны быть, поправьте куда плыть, пожалуйста, а то я что-то малость запутался...


Название: Re: Command output in "real time'
Отправлено: andrewshkovskii от Апрель 19, 2010, 09:27
Код
C++ (Qt)
connect(term_command,SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(exitProcess()));
а кто же у тебя принимает сигнал finished() ?
Или это
Цитировать
connect(sender, signal, this, method, type).
?
Насчет краша, без кода я могу лишь наивно предположить, что после того, как процесс завершился у тебя, у тебя где-то ещё происходит обращение в этому казателю.


Название: Re: Command output in "real time'
Отправлено: BRE от Апрель 19, 2010, 10:23
Если мысли не там, где должны быть, поправьте куда плыть, пожалуйста, а то я что-то малость запутался...
Я тебе очень не рекомендую в слотах-приемниках уничтожать объект, который генерирует сигнал инициатор. Для этого лучше использовать слот QObject::deleteLater.


Название: Re: Command output in "real time'
Отправлено: Az от Апрель 19, 2010, 17:25
Всем спасибо за помощь! Разобрался  :)