#qt #qt5
Есть приложение на Qt, включающее код такого вида :
QProcess proc;
...
proc.setProgramm("Python34\\python");
proc.setArguments(QStringList{"hello.py"});
proc.setProcessChannelMode(QProcess::MergedChannels);
connect(&proc, &QProcess::readyReadStandardOutput, []() {
QString output = QString(proc.readAllStandardOutput());
...
});
proc.start();
Но readyReadStandardOutput отлавливается только после завершения процесса. В моём
случае - требуется проделать определённые действия до завершения (по наличию в выводе
определённого текста).
Как это реализовать?
upd. Более подробный код имеет вид :
class Window: public QMainWindow {
...
private:
QVector processes;
void createProcesses();
void prepareProcess(QProcess* proc);
}
void MainWindow::createProcesses() {
for(int i=0;...) {
processes.append(new QProcess());
prepareProcess(&processes[processes.size()-1]);
}
}
void MainWindow::prepareProcess(QProcess* proc) {
proc->setProgramm("Python34\\python");
proc->setArguments(QStringList{"hello.py"});
proc->setProcessChannelMode(QProcess::MergedChannels);
connect(&proc, &QProcess::readyReadStandardOutput, []() {
QString output = QString(proc->readAllStandardOutput());
...
});
proc->start();
}
UPD. А в Qt ли вообще дело? Обнаружил следующее.
При запуске, например ping /t ya.ru результат выводится. Но, с применением например,
следующего питоноскрипта - нет
import time
while True:
print("Hello")
time.sleep(1)
Ответы
Ответ 1
В справке по обозначенному сигналу говорится, что последний будет отправляться по мере поступления новых данных. То есть не по завершению процесса, а именно во время работы процесса. Метод QProcess::start() является асинхронным. Объект QProcess у Вас создаётся в стеке. В связи с этим, возможно, что проблема заключается в несвоевременном уничтожении объекта, либо в отсутствии вызова цикла событий, что в свою очередь ведёт к помещению отправленного сигнала в очередь. Соответственно, и получается, что сигнал доходит постфактум, а не тогда, когда его вызвали. Создавайте объект QProcess в куче (через new), либо после вызова метода QProcess::start() при помощи QEventLoop активируйте локальный цикл событий. Ну или, как ещё один вариант, воспользуйтесь блокирующим ожиданием: QProcess::waitForReadyRead().Ответ 2
Дело было не в приложении на Qt, а в буферизации вывода python-ом (https://stackoverflow.com/questions/230751/how-to-flush-output-of-python-print) Лечится запуском с опцией -u
Комментариев нет:
Отправить комментарий