Будет ли блокироваться пользовательский интерфейс при ожидании QThread / Как правильно использовать QThread - PullRequest
0 голосов
/ 25 марта 2019

Если у меня есть индикатор выполнения в потоке пользовательского интерфейса (окне), который будет работать бесконечно, пока метод не завершит свою работу, будет ли поток пользовательского интерфейса блокироваться, и поэтому индикатор выполнения, если я жду, пока завершится второй QThread?Если поток пользовательского интерфейса блокирует ожидание, то я бы не стал ждать второго потока.Я подумал реализовать метод обратного вызова, который будет вызываться после завершения второго потока, но затем: Как я могу подключиться к методу обратного вызова?

Что я хочу сделать?У меня есть окно, в этом окне есть индикатор выполнения, который сначала не виден.Когда пользователь нажимает определенную кнопку для запроса данных, вызывается метод, который возвращает RequestPointer, который содержит метод, который возвращает статус запроса.Когда пользователь нажимает кнопку, я хочу, чтобы индикатор выполнения отображался непрерывно до тех пор, пока запрос не будет завершен, и я смогу распечатать данные в окне.Работнику я хочу передать этот указатель, и работник проверяет цикл while (flag), если статус все еще работает, и спит, если так.Когда рабочий заканчивает, я хочу остановить индикатор выполнения и снова сделать его невидимым.Нужно ли передавать индикатор выполнения потоку, или я могу ждать потока, не блокируя пользовательский интерфейс?

Я не совсем профессионал в Qt.Действительно новый для этого.Я пытался получить некоторую информацию с веб-сайта https://doc.qt.io/Qt-5/qthread.html, но мне немного трудно понять пример кода.

Метод в моем рабочем классе:

void Worker::watchRequest(RequestPtr r_ptr)
{
    bool exit = true;

    while (!exit)
    {
        ErrorCode errorCode = r_ptr->Test();

        switch (errorCode)
        {
        case Request_RUNNING:   
            QThread::msleep(10);
            break;
        case Request_ABORTED:
            exit = true;
            break;
        case Request_SUCCESS:
            exit = true;
            break;
        }

    }

Ответы [ 3 ]

2 голосов
/ 25 марта 2019

QThread имеет сигнал finished. Подключите его к соответствующему слоту, который будет запускать любые действия, необходимые для завершения потока.

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

В качестве альтернативы вы можете использовать QTimer для чтения текущего прогресса время от времени (это похоже на то, что у вас есть сейчас, но не блокирует пользовательский интерфейс).

1 голос
/ 25 марта 2019

Если вы не хотите блокировать пользовательский интерфейс, все, что вам нужно сделать, это вызвать QApplication::processEvents(); в вашем цикле while.

У меня есть код, который использует std :: future вместо QThread, и мой код выглядит так:

while (!progressIndicator->UserBreak()
    && (future.wait_for(std::chrono::seconds(0)) != std::future_status::ready))
{
    QApplication::processEvents();
}

Это хорошо работает.

0 голосов
/ 25 марта 2019

Чтобы обновить индикатор выполнения потока пользовательского интерфейса во время выполнения операции, используйте объект QTimer для увеличения значения индикатора выполнения (максимальное значение будет: на единицу меньше значения индикатора выполнения после завершения операции). Также подключите QThread к слоту методом Signal / Slot, чтобы сигнализировать потоку пользовательского интерфейса о завершении операции. Когда QThread завершает операцию, отправьте сигнал в слот в потоке пользовательского интерфейса, который установит конечное значение индикатора выполнения, а также остановит QTimer.

...