Přístup k widgetům

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 kontroluje widget na prázdný ukazatel a na očekávaný typ a případně o těchto problémech vypíše varování do příkazové řádky.

Pamatujte, že instanci widgetu nevytváříte pomocí metody get_widget(), tou jen získáváte ukazatel na instanci, která již existuje. Pokaždé, když zavoláte get_widget() na ten samý objekt Gtk::Builder, měli byste obdržet ukazatel na tu samou instanci. Instance widgetů se vytváří během 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.

Reference

24.2.1. Příklad

Tento příklad ukazuje, jak načíst soubor Glade za běhu a jak přistupovat k widgetům pomocí Gtk::Builder.

Source Code

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);
}