Я только что написал некоторый код на основе QThread, который выполняет большие вычисления. Чтобы визуализировать прогресс, мне нужно открыть QProgressDialog. Диалог является модальным приложения (с использованием open ()), так как я не хочу разрешать изменения главного окна во время расчета. Поток испускает различные сигналы, которые позволяют конечному автомату связываться между GUI и потоком.
Два из сигналов, излучаемых рабочим объектом потока, — это «Progress» и «Finished». Если выдается «Progress», я обновляю QProgressDialog, используя setValue (). Если выбрано «Готово», диалог уничтожается.
В конце расчета происходит следующее:
QProgressDialog ломает мою архитектуру, вызывая processEvents () в setValue (). Также мои соглашения о кодировании запрещают использование любых вложенных циклов событий (как в exec () и т. Д.).
У меня есть два вопроса:
Почему модальный диалог требует вложенного цикла событий? Из моего непонимания блокирование ввода родительских окон, кажется, не требует этого.
Можно ли использовать QProgressDialog модальным способом, но без вложенного цикла событий?
ты должен использовать 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) …
Других решений пока нет …