met*_*dos 52 c++ checkbox qt signals-slots
我们有一个QCheckBox对象,当用户检查它或删除检查时我们想要调用一个函数,所以我们将函数连接到stateChanged ( int state )signal.另一方面,根据某些条件,我们还会改变QCheckBox代码内部的对象状态,这会导致不需要的信号.
在某些情况下有没有办法防止发射信号?
Job*_*Job 78
您可以使用该clicked信号,因为它仅在用户实际单击复选框时发出,而不是在您使用手动检查时发出setChecked.
如果您只是不希望在特定时间发出信号,可以QObject::blockSignals像这样使用:
bool oldState = checkBox->blockSignals(true);
checkBox->setChecked(true);
checkBox->blockSignals(oldState);
Run Code Online (Sandbox Code Playgroud)
这种方法的缺点是所有信号都将被阻止.但我想这对于一个案例来说并不重要QCheckBox.
Cal*_*itt 36
您始终可以使用阻止QObjects上的信号发射QObject::blockSignals().请注意,要正确处理事物,您应该记住旧状态(从函数调用返回),并在完成后恢复它.
在我的工作中,我们更喜欢RAII这类事情.一个简单的类可能如下所示:
class SignalBlocker
{
public:
SignalBlocker( QObject *obj ) : m_obj( obj ), m_old( obj->blockSignals( true ) )
{
}
~SignalBlocker()
{
m_obj->blockSignals( m_old );
}
private:
QObject *m_obj;
bool m_old;
};
Run Code Online (Sandbox Code Playgroud)
编辑:从Qt 5.3开始,请参阅QSignalBlocker(在评论中h/t到HappyCactus)
Boo*_*jum 12
在学习Qt时,我遇到了一系列互连的小部件,我想要"原子地"更新.我喜欢@ cjhuitt的解决方案,但发现基于代理对象的一些语法糖会更好.这是我用过的方法......
首先,我为阻止代理对象定义了一个类模板.像Caleb一样,它会阻挡构造上的信号,然后在破坏时恢复它们之前的状态.但是,它还会重载->操作符以返回指向被阻止对象的指针:
template<class T> class Blocker {
T *blocked;
bool previous;
public:
Blocker(T *blocked)
: blocked(blocked),
previous(blocked->blockSignals(true)) {}
~Blocker() { blocked->blockSignals(previous); }
T *operator->() { return blocked; }
};
Run Code Online (Sandbox Code Playgroud)
接下来,我定义了一个小模板函数来构造并返回一个Blocker:
template<class T> inline Blocker<T> whileBlocking(T *blocked) {
return Blocker<T>(blocked);
}
Run Code Online (Sandbox Code Playgroud)
把这一切放在一起,我会像这样使用它:
whileBlocking(checkBox)->setChecked(true);
Run Code Online (Sandbox Code Playgroud)
要么
whileBlocking(xyzzySpin)->setValue(50);
Run Code Online (Sandbox Code Playgroud)
这让我获得了RAII的所有好处,在方法调用周围自动配对阻塞和恢复,但我不需要命名任何包装器或状态标志.这很好,很简单,而且非常简单.
小智 6
在QObject派生类中,您可以调用blockSignals(bool)以防止对象发出信号.例如:
void customChangeState(bool checked)
{
blockSignals(true);
ui->checkBox->setCheckState(Qt::Checked);
// other work
blockSignals(false);
}
Run Code Online (Sandbox Code Playgroud)
上述方法将改变检查状态而不点击stateChanged,或发出任何其他信号.