Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QCheckBox: how to differentiate between user-induced changes to state and those made programmatically?

Do I miss something or there is really no (ready / built-in) way to programmatically change the state of a QCheckBox without emitting the "void stateChanged ( int state )" signal?

The above-mentioned signal is emitted regardless of whether "void setCheckState ( Qt::CheckState state )" was called or the user changed the state via the ui, and there is no "stateEdited" signal like with the QLineEdit.

So, if there is no ready way to differentiate between programmatic and user-induced changes to the state of the QCheckBox, and the only options are subclassing / adding the "stateEdited" signal or fiddling with "void QObject::blockSignals( bool block )", why does this have to be so, i.e., is it an (some sort of) inconsistency (in Qt)?

like image 760
mlvljr Avatar asked Dec 06 '09 20:12

mlvljr


3 Answers

If you only need to be informed of user input, listen to

QAbstractButton::clicked( bool checked );

Otherwise connect to

QAbstractButton::toggled( bool checked );

or

QCheckBox::stateChanged( int state);
like image 142
TimW Avatar answered Oct 31 '22 14:10

TimW


An approach that works for all signals and widgets is to wrap the calls to setChecked() in a pair of blockSignals() calls:

const bool blocked = but->signalsBlocked();
but->blockSignals( true );
but->setChecked( true );
but->blockSignals( blocked );

or, with something every Qt programmer will have in his toolbox:

class QSignalBlocker {
    QObject * const o;
    const bool blocked;
public:
    explicit QSignalBlocker( QObject * o )
      : o( o ),
        blocked( o && o->signalsBlocked() )
    {
        if ( o ) o->blockSignals( true );
    }
    ~QSignalBlocker() { if ( o ) o->blockSignals( blocked ); }
};

a RAII class. Usage:

const QSignalBlocker blocker( but );
but->setChecked( true );

EDIT 2013-12-10: Qt 5.3 will have QSignalBlocker built-in.

like image 35
Marc Mutz - mmutz Avatar answered Oct 31 '22 13:10

Marc Mutz - mmutz


If you want to

programatically change the state of a QCheckBox

use setCheckState method.

P.S. I do not understand what does it mean

change the state of a QCheckBox ... emitting a "void stateChanged ( int state )" signal

Probably you should read Signals and Slots topic more carefully.

like image 1
Wildcat Avatar answered Oct 31 '22 15:10

Wildcat