Russian Qt Forum
Ноябрь 23, 2024, 17:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Command output in "real time'  (Прочитано 7741 раз)
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, то окно не появляется вообще.
Подскажите, пожалуйста, как можно сделать этот вывод в реальном времени?
« Последнее редактирование: Апрель 18, 2010, 21:02 от Az » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Апрель 18, 2010, 09:48 »

void QProcess::readyReadStandardOutput ()   [signal]
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Az
Гость
« Ответ #2 : Апрель 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);
    }
 
 
}

Но в выводе только пробелы, то бишь ничего...
« Последнее редактирование: Апрель 18, 2010, 13:40 от Az » Записан
MoPDoBoPoT
Гость
« Ответ #3 : Апрель 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();
...
}
 
Записан
Az
Гость
« Ответ #4 : Апрель 18, 2010, 14:31 »

Мой косяк, однако.  setProcessChannelMode прохлопал  Обеспокоенный

Спасибо, друг!  Улыбающийся
Записан
Az
Гость
« Ответ #5 : Апрель 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, я пока не понял.
« Последнее редактирование: Апрель 18, 2010, 22:06 от Az » Записан
BRE
Гость
« Ответ #6 : Апрель 18, 2010, 22:19 »

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

void QProcess::finished ( int exitCode, QProcess::ExitStatus exitStatus )   [signal]
Записан
Az
Гость
« Ответ #7 : Апрель 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(), но ее принудительный вызов и удаление переменной процесса походу ее просто крашит...
Если мысли не там, где должны быть, поправьте куда плыть, пожалуйста, а то я что-то малость запутался...
Записан
andrewshkovskii
Гость
« Ответ #8 : Апрель 19, 2010, 09:27 »

Код
C++ (Qt)
connect(term_command,SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(exitProcess()));
а кто же у тебя принимает сигнал finished() ?
Или это
Цитировать
connect(sender, signal, this, method, type).
?
Насчет краша, без кода я могу лишь наивно предположить, что после того, как процесс завершился у тебя, у тебя где-то ещё происходит обращение в этому казателю.
« Последнее редактирование: Апрель 19, 2010, 09:38 от andrewshkovskii » Записан
BRE
Гость
« Ответ #9 : Апрель 19, 2010, 10:23 »

Если мысли не там, где должны быть, поправьте куда плыть, пожалуйста, а то я что-то малость запутался...
Я тебе очень не рекомендую в слотах-приемниках уничтожать объект, который генерирует сигнал инициатор. Для этого лучше использовать слот QObject::deleteLater.
Записан
Az
Гость
« Ответ #10 : Апрель 19, 2010, 17:25 »

Всем спасибо за помощь! Разобрался  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.236 секунд. Запросов: 23.