I would personally have all the necessary signals connected to their corresponding signal handlers, aka. slots.
They would all mark their emission is "done", and there could be a check for the overall condition whether it is "done" and after each signal handler sets its own "done", there could be a global "done" check, and if that suffices, they would emit a "global done" signal.
Then you could also connect to that "global done" signal initially, and when the corresponding signal handler is triggered, you would know that is done unless the conditions changed in the meantime.
After the theoretical design, you would have something like this (pseudo code)
connect_signal1_to_slot1();
connect_signal2_to_slot2();
...
connect_global_done_signal_to_global_done_slot();
slotX: mark_conditionX_done(); if global_done: emit global_done_signal();
global_done_slot: do_foo();
You could probably also simplify by having only two signals and slots, namely: one for the local done operation that "marks" local signal done based on the argument passed, and then there would be the "global done" signal and slots.
The difference would be then the semantics, whether to use arguments with one signal and slot or many signals and slots without arguments, but it is the same theory in principle.