我正在尝试使用三个 QToolButtons 制作三个互斥的单选按钮(基本上;它们是子类)。我在设计器中将 Checkable 设置为true
,现在有两个问题:
- 它们需要相互排斥,即单击一个按钮应取消选中所有其他按钮。
- 始终只选中一个按钮。
第一个很容易通过以下连接到的插槽代码解决toggled(bool)
:
void Foo::slot_radio1(bool on) {
if (on) {
tb_radio2->setChecked(false);
tb_radio3->setChecked(false);
}
}
其他两个按钮也是如此。不好,但有效。第二个有点棘手,这就是我的问题发挥作用的地方。
在大多数 GUI 工具包中,如果需要,您可以在事件处理程序中取消事件,如果当前活动的按钮将被关闭,则可以在此处使用它来取消切换。但是,这适用于使用事件处理程序并传递可以修改的事件对象的系统。据我所知,使用信号/插槽,您是在事后处理事件并且对它们没有影响。除了您无论如何都无权访问事件数据的问题之外。我尝试过的天真但愚蠢的方法是
if (!on) {
tb_radio1->setChecked(true);
}
基本上是在未选中时重新检查按钮 - 这会导致堆栈溢出,因为它会递归地再次触发每个其他插槽,一次又一次,...
通常是否有一种很好且干净的方法来实现这一目标?我宁愿不断开插槽,更改状态并再次连接它们。对于使用 Qt 多年的任何人来说,我可能会遗漏一些明显或微不足道的东西,但我想那不是我,因此它躲避了我。
现在有点乱了,但根据blockSignals
Tim 和 Andreas 的建议,它可以工作:
void WinPhoenix::slot_radio1(bool on) {
if (on) {
bool before2 = radio2->blockSignals(true);
bool before3 = radio3->blockSignals(true);
radio2->setChecked(false);
radio3->setChecked(false);
radio2->blockSignals(before2);
radio3->blockSignals(before3);
} else {
bool before = radio1->blockSignals(true);
radio1->setChecked(true);
radio1->blockSignals(before);
}
}