Read GTK Radio Button signal only when selected

懵懂的女人 提交于 2019-12-11 04:54:52

问题


GTK's "toggled" signal fires when a radio button is selected, but before that, it also fires upon deselection of the previously selected radio button.

I am working with a GUI that uses radio buttons, each representing a group of entities. The first of the pair of "toggled" signals is triggering some unwanted updates to other fields in the GUI -- updates that I only want to happen when the newly selected button triggers the callback. How do I work around this signal and limit the callback function to only operate on selection instead of deselection? I've considered a flag variable within the class I'm coding, but perhaps there is a more GTK-approved technique.


回答1:


I don't think you can only get selection signals, but you can do something else. You can write your signal handler so it gets the button that was toggled (assuming you are reusing the same handler for several buttons). Then you can check its state to see if it was selected or deselected.

The way you do this is to connect with an adapter:

// 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
   )
);

In your class, handle_button_toggled includes the button parameter:

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

In C++11, you can alternatively use a lambda expression:

buttona.signal_toggled().connect([this,&buttona]{
  handled_button_toggled(buttona); 
});



回答2:


// 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);
    // ...
  }

};


来源:https://stackoverflow.com/questions/13385024/read-gtk-radio-button-signal-only-when-selected

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!