3 つの QToolButtons を使用して相互に排他的な 3 つのラジオ ボタンを作成しようとしています (基本的に、それらはサブクラス化されています)。デザイナでCheckable を設定するtrue
と、次の 2 つの問題が発生します。
- これらは相互に排他的である必要があります。つまり、1 つのボタンをクリックすると、他のすべてのチェックが外されます。
- チェックされているボタンは常に 1 つだけです。
最初のものは、に接続された次のスロット コードで簡単に解決できましたtoggled(bool)
。
void Foo::slot_radio1(bool on) {
if (on) {
tb_radio2->setChecked(false);
tb_radio3->setChecked(false);
}
}
他の 2 つのボタンについても同様です。良くありませんが、機能します。2 つ目は少しトリッキーで、ここで私の質問の出番です。
ほとんどの 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);
}
}