Prevent Firing Signals in Qt

前端 未结 8 957
佛祖请我去吃肉
佛祖请我去吃肉 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:27

    You can QObject::disconnect to remove the corresponding signal-slot connection and can QObject::connect again once you are done...

    0 讨论(0)
  • 2020-12-14 14:29

    Even in QT5, its a bit cumbersome when there are many/several things to block. Here's a multi-object version that is concise to use:

    class SignalBlocker
    {
    public:
      SignalBlocker(QObject *obj)
      {
        insert( QList<QObject*>()<<obj );
      }    
      SignalBlocker(QList<QObject*>  objects)
      {
        insert(objects);
      }    
      void insert(QList<QObject*>  objects)
      {
        for (auto obj : objects)
          m_objs.insert(obj, obj->signalsBlocked());
        blockAll();
      }    
      void blockAll() {
        for( auto m_obj : m_objs.keys() )
          m_obj->blockSignals(true);
      }    
      ~SignalBlocker()
      {
        for( auto m_obj : m_objs.keys() )
          m_obj->blockSignals( m_objs[m_obj] );
      }    
    private:
      QMap<QObject*,bool> m_objs;      
    };
    

    usage:

    void SomeType::myFunction()
    {
        SignalBlocker tmp( QList<QObject*>() 
        << m_paramWidget->radioButton_View0
        << m_paramWidget->radioButton_View1
        << m_paramWidget->radioButton_View2
        );
        // Do more work, ... 
    }
    
    0 讨论(0)
  • 2020-12-14 14:30

    Qt5.3 introduced the QSignalBlocker class that does exactly what needed in an exception safe way.

    if (something) {
       const QSignalBlocker blocker(someQObject);
       // no signals here
    }
    
    0 讨论(0)
  • 2020-12-14 14:31

    You can use the clicked signal because it is only emitted when the user actually clicked the check box, not when you manually check it using setChecked.

    If you just don't want the signal to be emitted at one specific time, you can use QObject::blockSignals like this:

    bool oldState = checkBox->blockSignals(true);
    checkBox->setChecked(true);
    checkBox->blockSignals(oldState);
    

    The downside of this approach is that all signals will be blocked. But I guess that doesn't really matter in case of a QCheckBox.

    0 讨论(0)
  • 2020-12-14 14:41

    In QObject derived classes, you can call blockSignals(bool) to prevent the object from emitting signals. So for example:

    void customChangeState(bool checked)
    {
        blockSignals(true);
        ui->checkBox->setCheckState(Qt::Checked);
        // other work
        blockSignals(false);
    }
    

    The above method would change the check state without clicked, stateChanged, or any other signals being emitted.

    0 讨论(0)
  • 2020-12-14 14:45

    When some UI element should not respond to user it is appropriate to disable it. So that user would know that this element is not accepting input.

    0 讨论(0)
提交回复
热议问题