Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt force QCheckBox to emit signal on setChecked

Tags:

qt

qt4

If I called QCheckBox::setChecked( x ) the toggled signal is only emitted if x is not the same as the current checkbox state. I understand the logic behind this, to avoid signaling if nothing has changed. However, in some situations where I have a more complicated widgets setup, I need the signal to always be emitted. This ensures anybody who has connected to the checkbox will receive the first state.

Is there a way to have QCheckBox::setChecked(bool) emit a signal regardless of whether the state has changed?


My simple workaround now is to just force the checkbox into multiple states by doing setChecked(!x) and setChecked(x). I was hoping for a more correct way of doing this.

like image 580
edA-qa mort-ora-y Avatar asked Aug 31 '11 13:08

edA-qa mort-ora-y


1 Answers

Looking into the QAbstractButton implementation, I found the following lines of code:

if (!d->checkable || d->checked == checked) {
    if (!d->blockRefresh)
        checkStateSet();
    return;
}

where checkStateSet is a virtual function. QCheckBox overrides this and emits a stateChanged() signal only if the state changed. I haven't tested this, but I think d->blockRefresh is set to false if you call QCheckBox::setChecked( ... ) directly.

If this is the case, it means you could subclass QCheckBox and override the checkStateSet() method to something like this:

void MyCheckBox::checkStateSet()
{
    QCheckBox::checkStateSet();
    if( m_oldState == checkState() )
    {
        // emit the signal here, as QCheckBox::checkStateSet() didn't do it.
        emit stateChanged( m_oldState );
    }
    else
    {
        // don't emit the signal as it has been emitted already,
        // but save the old state
        m_oldState = checkState();
    }
}

where the header file contains

private:
    Qt::CheckState m_oldState;

which must be initialised to Qt::Unchecked in the constructor.

like image 55
Tim Meyer Avatar answered Sep 28 '22 05:09

Tim Meyer