0

3 つの QToolButtons を使用して相互に排他的な 3 つのラジオ ボタンを作成しようとしています (基本的に、それらはサブクラス化されています)。デザイナでCheckable を設定するtrueと、次の 2 つの問題が発生します。

  1. これらは相互に排他的である必要があります。つまり、1 つのボタンをクリックすると、他のすべてのチェックが外されます。
  2. チェックされているボタンは常に 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);
    }
}
4

1 に答える 1

2

スロットを外したり、状態を変えたり、再度接続したりしたくありません。

QObject :: blockSignals()を使用して、オブジェクトによって送信されたシグナルを一時的に無効にすることができます。

bool before = tb_radio1->blockSignals(true);
tb_radio1->setChecked(true);
tb_radio1->blockSignals(before);

それ以外に、QActionGroup()を使用して相互排他性を実装することを検討できます。

于 2013-01-23T15:26:48.523 に答える