Acceso a 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 Glade Properties window. If the widget could not be found, or is of the wrong type, then the pointer will be set to nullptr.

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

Gtk::Builder verifica si el puntero es nulo y si el widget es del tipo esperado, y le advertirá en la línea de comandos de estos casos.

Recuerde que no está instanciando un widget con get_widget(), sólo está obteniendo un puntero a uno que ya existe. Siempre recibirá un puntero a la misma instancia cuando llame a get_widget() en el mismo Gtk::Builder con el mismo nombre de widget. Los widgets se instancian durante 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. Windows (such as Dialogs) 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.

Referencia

24.2.1. Ejemplo

Este ejemplo simple muestra cómo cargar un archivo Glade en tiempo de ejecución y acceder a los widgets con Gtk::Builder.

Código fuente

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

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

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

void on_button_clicked()
{
  if (pDialog)
    pDialog->hide(); //hide() will cause Gtk::Application::run() to end.
}

void on_app_activate()
{
  // Load the GtkBuilder file and instantiate its widgets:
  auto refBuilder = Gtk::Builder::create();
  try
  {
    refBuilder->add_from_file("basic.glade");
  }
  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::Dialog>("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.
  pDialog->signal_hide().connect([] () { delete pDialog; });

  app->add_window(*pDialog);
  pDialog->show();
}
} // 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);
}