Не могу получить вывод процесса в строку QT
Мне нужно считать вывод процесса QProcess в QString
QString program = "cmd", output;
command = "cd /d ";
command += QString::fromLocal8Bit(dir); //здесь хранится путь до папки, в которой должна исполняться команда
command += " & pip list";
qDebug() << command;
arg << "/C" << command;
QProcess *Process2 = new QProcess(this);
Process2->start(program, arg);
connect(Process2, &QProcess::readyReadStandardOutput, [&] {
QString output(Process2->readAll());
});
qDebug() << output;
Я проверил - команда, которая хранится в command - работает, но в строке qDebug() << output; я получаю значение "". С кодировкой всё в порядке (команда сама по себе выводится и её можно скопировать и вставить в cmd - она сработает). Как мне получить в строку output вывод этого процесса?
Ответы (2 шт):
В вашем варианте вы используте асинхронное апи, поэтому ваша лямбда вызовется непонятно в какое время и нельзя сразу после старта печатать вывод, надо делать это в самой лямбде
QString program = "cmd", output;
command = "cd /d ";
command += QString::fromLocal8Bit(dir); //здесь хранится путь до папки, в которой должна исполняться команда
command += " & pip list";
qDebug() << command;
arg << "/C" << command;
QProcess *Process2 = new QProcess(this);
// Лямбда выражение будет выполнено после вызова Process2->start
connect(Process2, &QProcess::readyReadStandardOutput, [&] {
output = QString::FromLocal8Bit(Process2->readAll());
qDebug() << output;
});
Process2->start(program, arg);
Вариант 2 - использовать синхронное апи (https://doc.qt.io/qt-5/qprocess.html#synchronous-process-api)
QString program = "cmd", output;
command = "cd /d ";
command += QString::fromLocal8Bit(dir); //здесь хранится путь до папки, в которой должна исполняться команда
command += " & pip list";
qDebug() << command;
arg << "/C" << command;
QProcess *Process2 = new QProcess(this);
connect(Process2, &QProcess::readyReadStandardOutput, [&] {
output = QString::FromLocal8Bit(Process2->readAll());
});
Process2->start(program, arg);
Process2->waitForFinished(); // Ждем завершения роцесса
qDebug() << output; // Во время waitForFinished, будет совершен асинхронный вызов лямбды, которая сохранит вывод в переменную и её можно использовать уже после завершения процесса
- зачем в лямбде повторное объявление переменной? почитайте про область видимости переменных. У вас получается две переменных с одним именем.
- В лямбде вы каждый раз переписываете значение, но данные будут поступать постепенно и у вас на руках останется только последняя порция.
- Работа сигналов-слотов АСИНХРОННАЯ. И ожидать в последней строке готового вывода бесполезно - qDebug() << output; отработает еще до того как в output появятся данные
Вот
QString program = "ping 127.0.0.1";
QString* output = new QString(); // лямбда будет с доступом к переменным по значению, поэтому тут у нас будет указатель
QProcess *Process = new QProcess(this);
Process->start(program);
connect(Process, &QProcess::readyReadStandardOutput, [=] {
output->append(Process->readAll()); // НЕ ПЕРЕПИСЫВАЕМ а дописываем
});
Process->waitForFinished(); // ЖДЕМ ЗАВЕРШЕНИЯ процесса
qDebug()<<output;
UPD: Еще как вариант, если все равно будет синхронная работа, обойтись без лямбд и сигналов:
QString program = "ping 127.0.0.1";
QProcess *Process = new QProcess(this);
Process->start(program);
Process->waitForFinished();
QString output = Process->readAllStandardOutput();
qDebug()<<output;
PS: сдается мне что вашу программу по итогу напишет сообщество SO. Я думал уж с этим то справитесь, тем более что на подобный вопрос уже отвечалось