如果我拨打QCheckBox::setChecked( x )
toggled
信号仅在x
与当前复选框状态不同时发出。我理解这背后的逻辑,如果没有任何改变,就避免发出信号。但是,在某些情况下,我有一个更复杂的小部件设置,我需要始终发出信号。这可以确保任何已连接到该复选框的人都将收到第一个状态。
无论状态是否发生变化,都有办法让QCheckBox::setChecked(bool)
发出信号吗?
我现在的简单解决方法是通过执行setChecked(!x)
和setChecked(x)
强制复选框进入多个状态。我希望有一个更正确的方法来做到这一点。
答案 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())