Hi Eric,
i have done the same thing a few times now (Parenting widgets under inherited dockwidgets if the user wants them dockable and needing to clean up stuff (QTimer etc.) ).
Maybe the reason that your closeEvent is not called when docked is, that you are actually closing the DockWidget and not your QDialog and therefore you are triggering the Dockwidgets closeEvent.
What you could do in this case would be to override the DockWidgets closeEvent, and from in there
1. Also clean up or
2. call the child QDialog closeEvent that cleans up.
Also, you could override the instance factory method (__new__) of your subclassed QDialog and search for instances of your custom QDialog type and if some are found,
schedule them for deletion via deleteLater(). This way, you would make sure that, before new instance creation, all old instances with timers etc. are cleaned.
I often have a clean_up() method called within closeEvents and a cleanup/deletion in __new__.
And it might be personal preference, but i would usually prefer to inherit from default Qt types, such as QDockWidget instead of specialized Maya types like maya.app.general.mayaMixin.MayaQWidgetDockableMixin if they basically do the same......but maybe that just personal.
Cheers,
Timm