Accessing widgets
| Chapter 26. Gtk::Builder |

## Accessing widgets

To access a widget, for instance to show a dialog, use the `get_widget()` method, providing the widget's name. This name should be specified in the Cambalache window. If the widget could not be found, or is of the wrong type, then the pointer will be set to `nullptr`.

The dialogs in this chapter are derived from `Gtk::Window` because `Gtk::Dialog` is deprecated since gtkmm 4.10.

    auto pDialog = builder->get_widget<Gtk::Window>("DialogBasic");

`Gtk::Builder` checks for a null pointer, and checks that the widget is of the expected type, and will show warnings on the command line about these.

Remember that you are not instantiating a widget with `get_widget()`, you are just obtaining a pointer to one that already exists. You will always receive a pointer to the same instance when you call `get_widget()` on the same `Gtk::Builder`, with the same widget name. The widgets are instantiated during `Gtk::Builder::create_from_file()`.

`get_widget()` returns child widgets that are `manage()`ed (see the Memory Management chapter), so they will be deleted when their parent container is deleted. `Window`s (such as `Dialog`s) cannot be managed because they have no parent container, so you must delete them at some point. The documentation of `Gtk::Builder` has more to say about the memory management of different kinds of objects.

Reference

### Example

This simple example shows how to load a `.ui` file at runtime and access the widgets with `Gtk::Builder`.

Source Code

File: `main.cc` (For use with gtkmm 4)

    #include <gtkmm.h>
    #include <iostream>

    namespace
    {
    Gtk::Window* pDialog = nullptr;
    Glib::RefPtr<Gtk::Application> app;

    void on_button_clicked()
    {
      // When the application's only window is removed with
      // unset_application(), Gtk::Application::run() will end.
      if (pDialog)
        pDialog->unset_application();
    }

    void on_app_activate()
    {
      // Load the GtkBuilder file and instantiate its widgets:
      auto refBuilder = Gtk::Builder::create();
      try
      {
        refBuilder->add_from_file("basic.ui");
      }
      catch(const Glib::FileError& ex)
      {
        std::cerr << "FileError: " << ex.what() << std::endl;
        return;
      }
      catch(const Glib::MarkupError& ex)
      {
        std::cerr << "MarkupError: " << ex.what() << std::endl;
        return;
      }
      catch(const Gtk::BuilderError& ex)
      {
        std::cerr << "BuilderError: " << ex.what() << std::endl;
        return;
      }

      // Get the GtkBuilder-instantiated dialog:
      pDialog = refBuilder->get_widget<Gtk::Window>("DialogBasic");
      if (!pDialog)
      {
        std::cerr << "Could not get the dialog" << std::endl;
        return;
      }

      // Get the GtkBuilder-instantiated button, and connect a signal handler:
      auto pButton = refBuilder->get_widget<Gtk::Button>("quit_button");
      if (pButton)
        pButton->signal_clicked().connect([] () { on_button_clicked(); });

      // It's not possible to delete widgets after app->run() has returned.
      // Delete the dialog with its child widgets before app->run() returns.
      app->signal_window_removed().connect([](Gtk::Window* window) { delete window; });

      app->add_window(*pDialog);
      pDialog->set_visible(true);
    }
    } // anonymous namespace

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

      // Instantiate a dialog when the application has been activated.
      // This can only be done after the application has been registered.
      // It's possible to call app->register_application() explicitly, but
      // usually it's easier to let app->run() do it for you.
      app->signal_activate().connect([] () { on_app_activate(); });

      return app->run(argc, argv);
    }

Chapter 26. Gtk::Builder |  | Using derived widgets