GTK+ 我该如何找出哪个单选按钮被选中了?

6

这里的教程 http://developer.gnome.org/gtk-tutorial/2.90/x542.html 展示了如何设置单选按钮,但是忽略了告诉你如何使用它们。

那么我该如何找到哪个单选按钮被选中了呢?

我的解决方案:

使用以下代码初始化单选按钮:

rbutton1 = gtk_radio_button_new_with_label(NULL, "button1");
gtk_box_pack_start(GTK_BOX(rbutton_box), rbutton1, TRUE, TRUE, 0);

rbuttonGroup = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton1)); /*not sure what I'd use this line for currently though*/
rbutton2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rbutton1), "button 2"); 
gtk_box_pack_start(GTK_BOX(rbutton_box), rbutton2, TRUE, TRUE, 0);

rbutton3 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rbutton1), "button 3"); 
gtk_box_pack_start(GTK_BOX(rbutton_box), rbutton3, TRUE, TRUE, 0);

使用此方法更新一个变量,告诉您哪个单选按钮被选中:

        void checkRadioButtons()
{
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutton1))==TRUE) selectedRadioButton =1;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutton2))==TRUE) selectedRadioButton =2;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutton3))==TRUE) selectedRadioButton =3;
}
8个回答

5

谷歌将我引导至此,因为我在搜索Python / PyGTK / PyGTK3,所以我希望我可以发布一个PyGTK解决方案:

def _resolve_radio(self, master_radio):
    active = next((
        radio for radio in
        master_radio.get_group()
        if radio.get_active()
    ))
    return active

这里使用一个生成器来返回第一个(应该是唯一)处于活动状态的单选框。


2
这是我的建议:

这样做:

void radio_button_selected (GtkWidget *widget, gpointer data) 
{
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))
    {
        GSLIST *group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
        g_print ("Index = %i%\n", g_slist_index (group, widget));
    }
}

1

让我们创建一系列按钮:

for severity in levels:
    radio = gtk.RadioButton(group=radioButtons, label=severity)
    if severity == actualLevel:
        radio.set_active(True)
    hBox.pack_start(radio, True, True, 3)
    radio.connect('toggled', self.radioButtonSelected, severity)

而且所有的按钮都连接到同一个处理程序:

def radioButtonSelected(self, button, currentSeverity):
    # proceed with the task
    # as you can see, button is passed by as argument by the event handler
    # and you can, for example, get the button label :
    labelReadFromButton = button.getLabel()

1
这是我如何做到的。
GtkRadioButton * radio_button;
GtkRadioButton * radio_button1;
GtkRadioButton * radio_button2;
...
GSList * tmp_list = gtk_radio_button_get_group (radio_button);//Get the group of them.
GtkToggleButton *tmp_button = NULL;//Create a temp toggle button.

while (tmp_list)//As long as we didn't reach the end of the group.
{
  tmp_button = tmp_list->data;//Get one of the buttons in the group.
  tmp_list = tmp_list->next;//Next time we're going to check this one.

  if (gtk_toggle_button_get_active(tmp_button))//Is this the one active?
    break;//Yes.

  tmp_button = NULL;//We've enumerated all of them, and none of them is active.
}
//Here. tmp_button holds the active one. NULL if none of them is active.

请查看此处的讨论。 我不知道他们是否会将此功能添加到其中(似乎不会)。


0

你可以连接到GtkToggleButton::toggled信号上,然后在相关回调中更新变量。至于对gtk_radio_button_get_group的调用,只有当你调用gtk_radio_button_new_with_label而不是gtk_radio_button_new_with_label_with_widget时,才需要使用它,正如你所参考的教程中所述。


0

我的GTKmm解决方案非常简单,

你只需要调用这个函数:

my_radio_button.get_active(); \n

这将返回0(未激活)或1(已激活)。


0

如果你不想烦恼于繁琐的方法,可以使用lambda表达式,但仍需要使用connect,不过这样更容易阅读:

Enum RadioValues { A, B, C, none };

RadioValues values = RadioValues.none; // only needed if you dont have an initially selected radio button

MyConstructor()
{
   Build();
   // asumming you have 3 radio buttons: radioA, radioB, radioC:
   radioA.Toggled += (sender,e) => values = RadioValues.A;
   radioB.Toggled += (sender,e) => values = RadioValues.B;
   radioC.Toggled += (sender,e) => values = RadioValues.C;

}

就是这样,没有要处理的方法,而且你也不必局限于只使用它,如果你需要更多的灵活性,你还可以使用匿名函数-当然,接下来的步骤是使用方法。不幸的是,他们没有提供一个简单的.Checked属性,我的下一个建议是覆盖单选按钮本身,并在其切换状态改变时链接一个Checked属性,模仿其他框架如MFC、Qt和Winforms...等。

顺便说一下:为了简单起见,我省略了样板代码,这可能会使答案变得更加混乱,而你可能只想知道事实,而不是演示我是否能正确调用构造函数 :)


0

这是一个使用单选按钮的演示代码,您可以在其中找到我如何确定哪个单选按钮被选中:

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

你能否澄清一下这个回答如何回答所问的问题? - Skully
是的先生,我在第一行中添加了一个示例,展示了如何找到哪个单选按钮被选中。在回复您时,我意识到我使用的是gtkmm而不是问题所问的gtk+。很抱歉,但我认为这段代码仍然有用。 - Mario Galindo
我想澄清一下,我写了不同的连接信号的方式。第一种是我在C++11中的做法。您可以使用#if 1选择它,如果将if更改为#if 0,则会得到在gtkmm手册中解释的形式。但是,在那种情况下,我还写了三个替代方法来编写信号。 - Mario Galindo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接