2

GTK の「トグル」シグナルは、ラジオ ボタンが選択されたときに発生しますが、その前に、以前に選択されたラジオ ボタンの選択が解除されたときにも発生します。

それぞれがエンティティのグループを表すラジオ ボタンを使用する GUI を使用しています。「切り替えられた」シグナルの最初のペアは、GUI の他のフィールドへの不要な更新をトリガーしています。新しく選択したボタンがコールバックをトリガーしたときにのみ発生させたい更新です。このシグナルを回避し、コールバック関数が選択解除ではなく選択時にのみ動作するように制限するにはどうすればよいですか? コーディングしているクラス内でフラグ変数を検討しましたが、GTK で承認された手法がもっとあるかもしれません。

4

3 に答える 3

1

選択信号しか得られないと思いますが、他のことはできます。トグルされたボタンを取得するようにシグナルハンドラーを作成できます (複数のボタンに同じハンドラーを再利用していると仮定します)。次に、その状態をチェックして、選択されているか選択解除されているかを確認できます。

これを行う方法は、アダプターに接続することです。

// do this for each button (this one is for "buttona"):
buttona.signal_toggled().connect(
   sigc::bind(
      sigc::mem_fun(*this, &myclass::handle_button_toggled),
      buttona
   )
);

あなたのクラスでは、handle_button_toggled にボタン パラメータが含まれています。

myclass {
  Gtk::ToggleButton buttona, buttonb, ...
  ....
  void handle_button_toggled(Gtk::ToggleButton &b) {
   ...check state of b ...
  }
}

C++11 では、代わりにラムダ式を使用できます。

buttona.signal_toggled().connect([this,&buttona]{
  handled_button_toggled(buttona); 
});
于 2012-11-28T19:38:21.157 に答える
0
// C++11
#include <gtkmm.h>
#include <iostream>
#include <vector>

using namespace std;

class RadioBox
{
public:
    Gtk::Box                     {Gtk::ORIENTATION_HORIZONTAL};
    vector<Gtk::RadioButton*>    rb_list;
    string                       selected_text;
    int                          selected_pos;

    RadioBox(int defpos,
             std::initializer_list<string> rb_name)
    {
        add(box);
        int i = 0;
        for (auto& rb_name_i : rb_name) {
          Gtk::RadioButton* rb  = new Gtk::RadioButton{rb_name_i};
          rb_list.push_back(rb);
          if (i==defpos) {
            rb->set_active();
          }
          box.pack_start(*rb, 0, 0);
          if (i != 0) {
            rb->join_group(*rb_list[0]);
          }
          rb->signal_toggled().connect(
            sigc::bind(
              sigc::mem_fun(*this, &LabRadio::clicked),
              rb,
              i
            ));
          i++;
        }
    }

    void clicked(Gtk::RadioButton* rb, int pos) {
       if (!rb) return;
       if (rb->get_active()) {
         selected_pos  = pos;
         selected_text = rb->get_label().c_str();
         cout << "RadioButton:selected"
              << " pos:" << selected_pos
              << " text:" << selected_text
              << "\n";
       }
    }

    ~RadioBox() {
        rb_count = rb_list.size();
        for(int i=0; i < rb_count; ++i) {
          if (rb_list[i]) delete rb_list[i];
        }
    }

};


//USAGE:

class mywindow : public Gtk::Window {
  public:
    RadioBox myradiobox {2, {"Apples", "Pears", "Oranges", "Peaches"}};

  // ... your code here

  mywindow() {
    // ...
    <somewidget>.pack_start(myradiobox.box);
    // ...
  }

};
于 2016-12-19T18:55:36.723 に答える
0
This is a demo code using Radio Buttons, where you can find how I find which radio button is selected:
#include <gtkmm/window.h>
#include <gtkmm/box.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/separator.h>
#include <gtkmm/application.h>
#include <iostream>

class ButtonWindow : public Gtk::Window
{
private:
   //Child widgets:
   Gtk::Box m_Box_Top, m_Box1, m_Box2;
   Gtk::RadioButton m_RadioButton1, m_RadioButton2, m_RadioButton3;
   Gtk::Separator m_Separator;
   Gtk::Button m_Button_Close;
   Gtk::RadioButton *m_SelectedButton{nullptr};

public:
   ButtonWindow()
      : m_Box_Top(Gtk::ORIENTATION_VERTICAL),
        m_Box1(Gtk::ORIENTATION_VERTICAL, 15),
        m_Box2(Gtk::ORIENTATION_VERTICAL, 0),
        m_RadioButton1("button 1"),
        m_RadioButton2("button 2"),
        m_RadioButton3("button 3"),
        m_Button_Close("close")
   {
      // Set title and border of the window
      set_title("radio buttons");
      set_border_width(0);

      // Put radio buttons 2 and 3 in the same group as 1:
      m_RadioButton2.join_group(m_RadioButton1);
      m_RadioButton3.join_group(m_RadioButton1);

      // Add outer box to the window (because the window
      // can only contain a single widget)
      add(m_Box_Top);

      //Put the inner boxes and the separator in the outer box:
      m_Box_Top.pack_start(m_Box1);
      m_Box_Top.pack_start(m_Separator);
      m_Box_Top.pack_start(m_Box2);

      // Set the inner boxes' borders
      m_Box1.set_border_width(20);
      m_Box2.set_border_width(10);

      // Put the radio buttons in Box1:
      m_Box1.pack_start(m_RadioButton1);
      m_Box1.pack_start(m_RadioButton2);
      m_Box1.pack_start(m_RadioButton3);

      // Put Close button in Box2:
      m_Box2.pack_start(m_Button_Close);

      // Connect the button signals:
#if 1 // C++11: (change this to #if 0 to use the traditional way)
      m_RadioButton1.signal_clicked().connect([&]{on_radio_button_clicked(m_RadioButton1);});
      m_RadioButton2.signal_clicked().connect([&]{on_radio_button_clicked(m_RadioButton2);});
      m_RadioButton3.signal_clicked().connect([&]{on_radio_button_clicked(m_RadioButton3);});

      m_Button_Close.signal_clicked().connect([&]{on_close_button_clicked();});
#else // Traditional:
  m_RadioButton1.signal_clicked() // Full sigc
     .connect(sigc::bind(sigc::mem_fun(*this, &ButtonWindow::on_radio_button_clicked),
                         sigc::ref(m_RadioButton1)));

  m_RadioButton2.signal_clicked() // sigc && C++98
     .connect(std::bind(sigc::mem_fun(*this, &ButtonWindow::on_radio_button_clicked),
                        std::ref(m_RadioButton2)));

  m_RadioButton3.signal_clicked() // Full C++98
     .connect(std::bind(&ButtonWindow::on_radio_button_clicked, this,
                        std::ref(m_RadioButton3)));

      m_Button_Close.signal_clicked()
         .connect(sigc::mem_fun(*this, &ButtonWindow::on_close_button_clicked));
#endif

      // Set the second button active:
      m_RadioButton2.set_active();

      // Make the close button the default widget:
      m_Button_Close.set_can_default();
      m_Button_Close.grab_default();

      // Show all children of the window:
      show_all_children();
   }
  
protected:
   //Signal handlers:
   void on_radio_button_clicked(Gtk::RadioButton& button)
   {
      if(m_SelectedButton != &button && button.get_active())
      {
         m_SelectedButton = &button;
         std::cout << "Radio "<< m_SelectedButton->get_label() << " selected.\n";
      }
   }

   void on_close_button_clicked()
   {
      hide(); // Close the application
   }
};

int main(int argc, char *argv[])
{
   auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

   ButtonWindow button;

   //Shows the window and returns when it is closed.
   return app->run(button);
}
于 2020-08-13T22:59:38.490 に答える