Qt强制QCheckBox在setChecked上发出信号

时间:2011-08-31 13:50:02

标签: qt qt4

如果我拨打QCheckBox::setChecked( x ) toggled信号仅在x与当前复选框状态不同时发出。我理解这背后的逻辑,如果没有任何改变,就避免发出信号。但是,在某些情况下,我有一个更复杂的小部件设置,我需要始终发出信号。这可以确保任何已连接到该复选框的人都将收到第一个状态。

无论状态是否发生变化,都有办法让QCheckBox::setChecked(bool)发出信号吗?


我现在的简单解决方法是通过执行setChecked(!x)setChecked(x)强制复选框进入多个状态。我希望有一个更正确的方法来做到这一点。

4 个答案:

答案 0 :(得分:6)

查看QAbstractButton实现,我发现了以下几行代码:

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

其中checkStateSet是虚函数。 QCheckBox会覆盖此项并仅在状态更改时发出stateChanged()信号。 我没有对此进行测试,但如果您直接致电d->blockRefresh,我认为false设置为QCheckBox::setChecked( ... )

如果是这种情况,则意味着您可以继承QCheckBox并将checkStateSet()方法覆盖为以下内容:

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();
    }
}

头文件包含

private:
    Qt::CheckState m_oldState;

必须在构造函数中初始化为Qt::Unchecked

答案 1 :(得分:2)

以下是您的案例可能或不可能的另一种解决方案:

如果您可以100%确定您的信号和插槽已连接,然后复选框有机会更改其状态,则每个连接的类都可以安全地初始化,假设未选中复选框。这是因为复选框在构造时始终未选中。 这样,您可能无需在连接信号后调用setChecked()

但是,如果在复选框已经更改后有可能连接信号,则此方法不起作用。我自己并不是100%喜欢这种方法,但它可能是你的选择。

答案 2 :(得分:0)

一种方法是将QCheckBox子类化并在您需要的地方实现信号发射,例如:

class MyCheckBox : public QCheckBox
{
   Q_OBJECT
public:
   MyCheckBox(QWidget *parent = 0) : QCheckBox(parent) {};

   virtual void setChecked(bool checked) {
            QCheckBox::setChecked(checked); emit checkWasSet(checked);
            };
signals:
   void checkWasSet(bool value);

};

现在使用此类而不是常规QCheckBox类,只要设置了检查状态,就可以连接到checkWasSet()信号。

答案 3 :(得分:0)

您可以自己发出当前状态的信号:

checkbox.stateChanged.emit(checkbox.checkState())