Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ QProcess+QProgressBar

Автор: Kokos 18.6.2015, 21:47

Кому не трудно подскажите пожалуйста.
Решил сделать интерфейс для консольной программки на bash, в с++ не разбираюсь, но с помощью Qt Creator сделал форму, пару кнопок.
Есть скрипт который долго работает, хотел вывести статус его выполнения через QProgressBar, но не соображу как это сделать.

Пока код такой:

#include "widget.h"
#include "ui_widget.h"
#include <QProcess>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_2_clicked()
{
    QProcess process(this);
    process.startDetached("/opt/tall/ttings.sh");
}

void Widget::on_progressBar_valueChanged(int value)
{


}

Автор: wiz29 19.6.2015, 14:21

Через QProcess никак,
если только выполнение вашего скрипта не возвращает в аутпут процесса значение прогресса выполнения.

если же там простой скрипт состоящий построчно из команд, без циклов и тп фишек.
то этот файл можно выполнить последовательно, построчно.
Тогда все выглядит довольно просто:
1. Читается файл скрипта построчно, заполняется массив со строками
2. Потом последовательно выполняется через QtConcurrent::mappedReduced например
3. Используется QFutureWatcher для мониторинга процесса исполнения, который подключается к полосе прогресса.

Автор: Kokos 20.6.2015, 13:51

Если я проставлю в скрипте метки типа echo "progress=1" echo "progress=3"... как их читать и заставить progressBar сопоставлять их со своей шкалой?

Вчера весь день изучал документацию, но без наглядных примеров правильно сделать не получается, да и неправильно тоже.

Автор: wiz29 25.6.2015, 11:25

Все просто: процесс - это QIODevice.
Вкратце можно запустить его в отдельном потоке и через прокси объект нотифицировать о ходе прогресса или об ошибка, читая из него данные.

// поточная функция которую можно запустить используя метод QtConcurrent::run(ProcessExecutor, execData); например, из слота в главном потоке.
void ProcessExecutor(const ExecutionData& execData)
{
    // запускаем процесс.
    QProcess process;
    process.start(execData.processName, execData.args);
    if (process.waitForStarted())
    {
        QByteArray processData;
        while(process.waitForReadyRead())
        {
            processData.append(process.readAll());
            //добавить код для обработки текущего буфера данных от процесс.
            .................................
            //отправить нотификацию в основной поток через прокси объект.
            execData.proxyObject.sendNotification(value);
        }
    }
}

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)