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.
This simple example shows how to load a .ui
file at runtime and access the widgets with Gtk::Builder
.
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() { if (pDialog) pDialog->set_visible(false); // set_visible(false) 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.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. pDialog->signal_hide().connect([] () { delete pDialog; }); 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); }