У меня есть эта простая программа C ++:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QProcess ps;
QByteArray ba;
ps.start("ls J:");
ba = ps.readAllStandardOutput();
char *someData = ba.data();
cout << "Testing QProcess ..." << endl;
cout << someData << endl;
cout << "done!" << endl;
return a.exec();
}
Выход:
Testing QProcess ...done!
Если я запускаю «ls J:» из Windows cmd, это работает.
Что мне не хватает?
использование QIODevice :: waitForReadyRead () в цикле, и только после этого возвращается, затем вызвать readAllStandardOutput()
, Как сказано в документах, QProcess::readAllStandardOutput()
прочтет все имеется в наличии данных, но не буду ждать. И прежде чем вы начнете читать, вам нужно подождать, пока процесс начнется с QProcess::waitForStarted()
.
Быстрый непроверенный частичный код, заменить строку ba = ps.readAllStandardOutput();
с этим:
if (ps.waitForStarted(-1)) {
while(ps.waitForReadyRead(-1)) {
ba += ps.readAllStandardOutput();
}
}
// else report error or whatever
Это должно выйти из цикла, когда произошла ошибка или дочерний процесс завершился, но продолжайте чтение до тех пор, без тайм-аута.
Примечание: в «обычной» программе Qt у вас будет запущен цикл обработки событий, а затем вы не будете вызывать waitForReadyRead()
или другие подобные удобные функции. Они будут блокировать цикл событий и останавливать все остальное тоже. В такой программе вы бы предпочтительно используйте сигналы и слоты или, альтернативно, начните дурачиться с потоками (но это, как правило, не является предпочтительным, это просто добавляет ненужную сложность).
QProcess
документация Говорит, что QProcess
объект испускает сигналы, когда есть данные, доступные для чтения: readyRead()
а также readyReadStandardOutput()
а также readyReadStandardError()
,
Самый простой способ — подключить эти сигналы к вашим слотам и сделать чтение, например, с помощью. readAllStandardOutput()
там.
Конечно петля Гида работает также.