Re: gtkmm tutorial question



This minimal example compliments Reese's solution, using bind.

#include <gtkmm.h>
#include <iostream>
#include <string>
void my_button_clicked(std::string buttonIdStr);
int main(int argc, char** argv) {
  Gtk::Main mainloop(argc,argv);

  //Instantiate widgets
  Gtk::Window window;
  Gtk::VBox   vbox;
  Gtk::Button buttons[5];

  //Pack widgets, connect signals
  for(int i=0; i<5;i++) {
     std::stringstream ss;
     ss << i;
     std::string buttonIdStr = ss.str();

     //Bind the name of the button as an extra argument to the callback
     buttons[i].signal_clicked().connect(sigc::bind<std::string>(sigc::ptr_fun(&my_button_clicked), buttonIdStr));

     buttons[i].set_label(buttonIdStr);
     vbox.pack_start(buttons[i]);
  }
  window.add(vbox);

  //Show everything, run the main loop
  window.show_all();
  mainloop.run(window);
}

void my_button_clicked(std::string buttonIdStr) {
  std::cout << "Hi from button " << buttonIdStr << std::endl;
}

Michael


From: Reece Dunn <msclrhd googlemail com>
To: charles seedle rigaku com
Cc: gtkmm-list gnome org
Sent: Thursday, January 6, 2011 11:33:55 AM
Subject: Re: gtkmm tutorial question

On 6 January 2011 15:36, Charles Seedle <charles seedle rigaku com> wrote:
> In the gtkmm tutorial on single item containers (Scrolled window) there is
> an example of a table with multiple toggle buttons. Unfortunetly the example
> doesn’t show how you can identify if one of the toggle buttons have been
> clicked, just the close button. You can setup the callback for an array of
> buttons. My issue is how do you determine which toggle button it was that
> was clicked. It can be done in Gtk+ but it eludes me how to get access to
> that kind of info in Gtkmm.  Getting the signal connection and callback
> parmeters correct seems to be the trick.
>
> For each button:
>
> buttons[x]->signal_clicked().connect(sigc::mem_fun(*this,
> &ExampleWindow::on_button_clicked));
>
> void ExampleWindow::on_button_clicked ()
> {
> }
>
>
> This will connect the buttons but it doesn’t pass enough info to figure out
> which button got clicked. Any ideas would be appreciated.

The signal_clicked().connect method takes a function object (functor).
That is, a class/struct that implements operator(). For example, you
could use:

  struct Test
  {
      void operator()() { printf("pressed!\n"); }
  };

  buttons[x]->signal_clicked().connect(Test());

  Test()(); // prints: pressed!

The sigc::mem_fun function creates a functor that binds to a class
function (your on_button_clicked in the example) with the class
instance (*this).

There is also a sigc::bind helper that binds a value to a function
parameter. That is:

  sigc::bind(Test(), arg)

maps to

  Test::operator()(arg)

when called, and takes no arguments. e.g.

  struct Test
  {
      void operator()(int arg) { printf("pressed button %d!\n", arg); }
  };

  sigc::bind(Test(), 10)(); // prints: pressed button 10

So, in your example, you can have:

  buttons[x]->signal_clicked().connect(
      sigc::bind(sigc::mem_fun(*this, &ExampleWindow::on_button_clicked), x));

  void ExampleWindow::on_button_clicked (int i)
  {
      button_type *button = buttons[x];
      ...
  }

HTH,
- Reece
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
http://mail.gnome.org/mailman/listinfo/gtkmm-list





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]