Search code examples
c++user-interfacegtkmm

Add image to button when pressed


button1_on_image = Gtk::manage(new Gtk::Image{"button1_on.png"});   // Load icon
button1_off_image = Gtk::manage(new Gtk::Image{"button1_off.png"}); //   images
button1 = Gtk::manage(new Gtk::ToolButton{*button1_off_image});  // Create button
button1->set_tooltip_markup("Select one stick");                //   with image
button1->signal_clicked().connect(sigc::mem_fun(*this, 
    &Main_window::on_button1_click));
toolbar->append(*button1);

This is a snippet of code showing how I successfully make the button. The problem is that, when it is clicked I want "button1_on.png" to be shown instead of "button1_off.png", but I don't know how to do that.


Solution

  • Here is a code snippet that does what you want:

    1. When the window is initially created, the button is "Off".
    2. When the button is clicked, the button changes state to "On".

    Note that this is a minimal example, so clicking again on the button will not change its state back to "On", but I will leave this part to you, if it is a requirement for you.

    #include <gtkmm.h>
    
    int main(int argc, char *argv[])
    {
        auto app = Gtk::Application::create(argc, argv, "buttons.on.off");
    
        // Load images:
        Gtk::Image button1_on_image{"button1_on.png"};
        Gtk::Image button1_off_image{"button1_off.png"};
    
        // Create button:
        Gtk::ToolButton button1{button1_off_image};
        button1.set_tooltip_markup("Select one stick");
    
        // Create handler (as a lambda):
        const auto handler = [&button1, &button1_on_image, &button1_off_image]()
                             {
                                 // We change to "on" here (when clicked):
                                 button1.set_icon_widget(button1_on_image);
    
                                 // We make it visible:
                                 button1.show_all();
                             };
    
        button1.signal_clicked().connect(handler);
    
        // Add the button to the window.
        Gtk::Window window;
        window.add(button1);
    
        // Make the window visible:
        window.show_all();
    
        return app->run(window);
    }
    

    I made some simplifications to your snippet:

    1. List item
    2. I put everything on the stack (no new).
    3. The handler is a lambda.

    In my opinion, it makes the syntax clearer.