Задача такова: Существует консольное приложение, осуществляющее некоторое действие (в частности: копирование файла с сохранением времени доступа). Для данного приложения необходимо реализовать графический интерфейс. Решил реализовывать путем простого создания дочернего процесса и передачи ему необходимых аргументов из текстовых полей, и копирования данных из stdout процесса в свое текстовое поле. Данный подход дал желаемый результат за исключением маленькой детали:
Приложение выводит в консоль прогресс бар и возможно ошибки, если произошли. пример:
>App copy setup.ini test\setup.ini
18483968:18483968 bytes copied (100.000000%)
Обновление прогресс бара выглядит примерно так:
printf("\r%d:%d bytes copied (%f%%)", count, total, count / total)) * 100));
fflush(stdout);
Данный участок кода вызывается с некоторой периодичностью и создает видимость печати статуса в одной строке, что прекрасно работает в консоли. Однако при вызове из графической оболочки, в свое текстовое поле я получаю данные следующего характера:
204800:18483968 bytes copied (1.107987%)
409600:18483968 bytes copied (2.215974%)
........................................
18432000:18483968 bytes copied (99.718849%)
18483968:18483968 bytes copied (100.000000%)
Данные результаты наталкивают меня на мысль, что для процесса, запущенного с помощью QT fflush(stdout) не создает такого-же эффекта, как с консолью. Существует ли способ реализовать необходимое поведение в QT?
Код, считывающий stdout:
void Process::update_stdout()
{
_stdout = QString(_process->readAllStandardOutput());
}
Код, осуществляющий вызов процесса:
void StartProcess(Process &process, const QString &prog, const QStringList
&args, QTextEdit *text_edit_for_stdout)
{
process.raw_process()->start(prog, args);
process.raw_process()->waitForStarted(-1);
do
{
process.raw_process()->waitForFinished(100);
}
while (process.raw_process()->state() == QProcess::Running);
text_edit_for_stdout->clear();
text_edit_for_stdout->setText(process.get_stdout());
ShowMessageBox("Action finished");
}
Решил проблему, исправив код обновления строки состояния:
Убрал этот код:
printf("\r%d:%d bytes copied (%f%%)", count, total, count / total)) * 100));
fflush(stdout);
Вместо него добавил этот:
std::cout.clear();
std::cout << std::flush << std::fixed << "\r" << count<< ":" << total<< " bytes copied (" << (double)(((double)((double)count/ (double)total)) * 100) << "%)";
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости