Prevent Firing Signals in Qt

前端 未结 8 966
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-14 14:07

We have a QCheckBox object, when user checks it or removes check we want to call a function so we connect our function to stateChanged ( int state )

8条回答
  •  太阳男子
    2020-12-14 14:48

    While learning Qt, I ran into this problem with a set of interconnected widgets that I wanted to update "atomically". I liked @cjhuitt's solution, but found that it goes even better with a bit of syntactic sugar based on proxy objects. Here's the approach that I used...

    First, I defined a class template for a blocker proxy object. Like Caleb's, this blocks the signals on construction, and then restores their previous state on destruction. However, it also overloads the -> operator to return a pointer to the blocked object:

    template class Blocker {
        T *blocked;
        bool previous;
    public:
        Blocker(T *blocked)
            : blocked(blocked),
              previous(blocked->blockSignals(true)) {}
        ~Blocker() { blocked->blockSignals(previous); }
        T *operator->() { return blocked; }
    };
    

    Next, I defined a small template function to construct and return a Blocker:

    template inline Blocker whileBlocking(T *blocked) {
        return Blocker(blocked);
    }
    

    Putting this all together, I'd use it like this:

    whileBlocking(checkBox)->setChecked(true);
    

    or

    whileBlocking(xyzzySpin)->setValue(50);
    

    This gets me all the benefits of RAII, with automatically paired blocking and restore around the method call, but I don't need to name any wrapper or state flags. It's nice, easy, and pretty darn foolproof.

提交回复
热议问题