Qt. Неблокирующее диалоговое окно прогресса при огромном количестве неконтролируемых вычислений - PullRequest
0 голосов
/ 04 мая 2020

Я реализовал виджет / диалог, который представляет собой просто анимацию внутри (CircularProgressDlg). Наше приложение состоит из диалоговой части входа и части главного окна. Между входом в систему и полным загрузкой MainWindow есть 5-10 секунд огромной функции init ().

Мне нужно запустить CircularProgressDlg, когда вход в систему принят, и мне нужно, чтобы он оживил его. -blocking. Я не могу использовать "update" или "processEvents" внутри этой огромной функции "init", потому что она очень сложна внутри и не будет достаточно гладкой.

Очень похоже, что этот тип диалогов , оторванный от главного события l oop, существует! Так как этого добиться? Я понимаю, что могу создать отдельный процесс с этим CircularProgressDlg, но давайте оставим этот путь до конца.

Каковы другие способы? Мы используем QtWidgets, но, возможно, я смогу реализовать небольшой диалог QML для таких случаев, если, конечно, QML решит мою проблему. Будет ли он? Какие варианты у меня есть?

Ответы [ 2 ]

3 голосов
/ 04 мая 2020

Используйте библиотеку Qt Concurrent, в частности ее QConcurrent::run метод , чтобы создать поток для вашей дорогой задачи. Вы получаете QFuture, который вы можете смотреть с помощью QFutureWatcher.

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

  • Создание QFutureWatcher, который будет сигнализироваться, когда будущее сделано:
    imageScaling = new QFutureWatcher<QImage>(this);
    connect(imageScaling, &QFutureWatcher<QImage>::resultReadyAt, this, &Images::showImage);
    connect(imageScaling, &QFutureWatcher<QImage>::finished, this, &Images::finished);
  • Создание будущего:
    std::function<QImage(const QString&)> scale = [imageSize](const QString &imageFileName) {
        QImage image(imageFileName);
        return image.scaled(QSize(imageSize, imageSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    };
    QFuture<QImage> fut = QConcurrent::run(scale, "test.png");
  • Прикрепление будущего к будущему наблюдателю:
    imageScaling->setFuture(fut);
0 голосов
/ 05 мая 2020

Спасибо всем. Мы решили сделать все правильно и реорганизовать загрузку и обновление наших виджетов неблокирующим способом. С перемещением всех возможных логов c в отдельных процессах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...