Всем спасибо. Я отписал ответ в той теме на stackoverflow.
В двух словах: получилось закрыть сначала модальные, а потом обычные. Моя проблема была в том, что в цикле поиска модальных присутствовал тест на
!w->objectName().isEmpty()
, который фильтровал MessageBox'ы.
Поскольку QWidget::close() использует deleteLater, то виджеты удаляются в правильном порядке.