Модальный QProgressDialog :: setValue () вызывает сбой вложенным циклом событий

Я только что написал некоторый код на основе QThread, который выполняет большие вычисления. Чтобы визуализировать прогресс, мне нужно открыть QProgressDialog. Диалог является модальным приложения (с использованием open ()), так как я не хочу разрешать изменения главного окна во время расчета. Поток испускает различные сигналы, которые позволяют конечному автомату связываться между GUI и потоком.

Два из сигналов, излучаемых рабочим объектом потока, — это «Progress» и «Finished». Если выдается «Progress», я обновляю QProgressDialog, используя setValue (). Если выбрано «Готово», диалог уничтожается.

В конце расчета происходит следующее:

  • Событие «Прогресс» (100%) выброшено
  • «Готово» испускается сразу после
  • setValue (100) вызывается из-за события «Progress»
  • Поскольку диалог модальный, setValue () вызывает processEvents ()
  • processEvents () доставляет событие «Завершено»
  • Событие «Завершено» приводит к разрушению диалога в середине
    setValue (), которая вызывает сбой

QProgressDialog ломает мою архитектуру, вызывая processEvents () в setValue (). Также мои соглашения о кодировании запрещают использование любых вложенных циклов событий (как в exec () и т. Д.).

У меня есть два вопроса:

  1. Почему модальный диалог требует вложенного цикла событий? Из моего непонимания блокирование ввода родительских окон, кажется, не требует этого.

  2. Можно ли использовать QProgressDialog модальным способом, но без вложенного цикла событий?

0

Решение

ты должен использовать deleteLater() уничтожить твой QProgressDialog, Событие, которое удаляет ваш QProgressDialog Объект обрабатывается в функции, которая принадлежит QProgressDialog Сам объект, это сводится к законности вызова delete this; внутри функции-члена C ++, вы можете обратиться к этот вопрос из isocpp C ++ FAQ для получения дополнительной информации об этом. Суть в том, что вы должны гарантировать, что вы больше не получите доступ к любому члену объекта после совершение самоубийства

так как вы не можете гарантировать это в Qt’s QProgressDialog::setValue() реализация, событие, которое deleteс QProgressBar как это будет счастливо вызывать UB при следующем доступе к любому члену объекта (когда поднят в функции-члене). deleteLater был специально разработан для решения этой проблемы, поскольку события отложенного удаления обрабатываются особым образом (они не обрабатываются QCoreApplication::processEvents()). Это означает, что QProgressDialog объект будет уничтожен после setValue возвращает управление в цикл событий, а не в середине выполнения setValue

Всегда используйте deleteLater в таких ситуациях При использовании равнины delete внутри события вы должны убедиться, что это событие не обрабатывается при выполнении функции-члена этого объекта, и что оно не выполняется в результате испускания сигнала от этого объекта (с прямым сигналом / слот соединения), поскольку, в конце концов, сигнал — это просто функция-член, реализация которой обеспечивается MOC Qt) …

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]