Depending on how complex things get, it might make sense to have a "data aggregation layer" between logic and UI. Basically, a UI element would only be connected to a single signal of the aggregation layer, and the aggregation layer would keep track of data changes, and would know when to emit that one signal. It doesn't reduce complexity, but it cleanly distributes it between two parts of your program.