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

## Using derived widgets

You can use Glade to layout your own custom widgets derived from gtkmm widget classes. This keeps your code organized and encapsulated. Of course you won't see the exact appearance and properties of your derived widget in Glade, but you can specify its location and child widgets and the properties of its gtkmm base class.

Use `Gtk::Builder::get_widget_derived()` like so:

    DerivedDialog* pDialog = 0;
    builder->get_widget_derived("DialogBasic", pDialog);

Your derived class must have a constructor that takes a pointer to the underlying C type, and the `Gtk::Builder` instance. All relevant classes of gtkmm typedef their underlying C type as `BaseObjectType` (`Gtk::Dialog` typedefs `BaseObjectType` as GtkDialog, for instance).

You must call the base class's constructor in the initialization list, providing the C pointer. For instance,

    DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
    : Gtk::Dialog(cobject)
    {
    }

You could then encapsulate the manipulation of the child widgets in the constructor of the derived class, maybe using `get_widget()` or `get_widget_derived()` again. For instance,

    DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
    : Gtk::Dialog(cobject),
      m_builder(builder),
      m_pButton(0)
    {
      //Get the Glade-instantiated Button, and connect a signal handler:
      m_builder->get_widget("quit_button", m_pButton);
      if(m_pButton)
      {
        m_pButton->signal_clicked().connect( sigc::mem_fun(*this, &DerivedDialog::on_button_quit) );
      }
    }

### Example

This example shows how to load a Glade file at runtime and access the widgets via a derived class.

Source Code

File: `deriveddialog.h` (For use with gtkmm 3, not gtkmm 2)

    #ifndef GTKMM_EXAMPLE_DERIVED_DIALOG_H
    #define GTKMM_EXAMPLE_DERIVED_DIALOG_H

    #include <gtkmm.h>

    class DerivedDialog : public Gtk::Dialog
    {
    public:
      DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);
      virtual ~DerivedDialog();

    protected:
      //Signal handlers:
      void on_button_quit();

      Glib::RefPtr<Gtk::Builder> m_refGlade;
      Gtk::Button* m_pButton;
    };

    #endif //GTKMM_EXAMPLE_DERIVED_WINDOW_H

File: `main.cc` (For use with gtkmm 3, not gtkmm 2)

    #include "deriveddialog.h"
    #include <iostream>

    int main (int argc, char **argv)
    {
      Gtk::Main kit(argc, argv);

      //Load the Glade file and instiate its widgets:
      Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
      try
      {
        refBuilder->add_from_file("derived.glade");
      }
      catch(const Glib::FileError& ex)
      {
        std::cerr << "FileError: " << ex.what() << std::endl;
        return 1;
      }
      catch(const Glib::MarkupError& ex)
      {
        std::cerr << "MarkupError: " << ex.what() << std::endl;
        return 1;
      }
      catch(const Gtk::BuilderError& ex)
      {
        std::cerr << "BuilderError: " << ex.what() << std::endl;
        return 1;
      }

      //Get the GtkBuilder-instantiated dialog::
      DerivedDialog* pDialog = 0;
      refBuilder->get_widget_derived("DialogDerived", pDialog);
      if(pDialog)
      {
        //Start:
        kit.run(*pDialog);
      }

      delete pDialog;

      return 0;
    }

File: `deriveddialog.cc` (For use with gtkmm 3, not gtkmm 2)

    #include "deriveddialog.h"

    DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade)
    : Gtk::Dialog(cobject),
      m_refGlade(refGlade),
      m_pButton(0)
    {
      //Get the Glade-instantiated Button, and connect a signal handler:
      m_refGlade->get_widget("quit_button", m_pButton);
      if(m_pButton)
      {
        m_pButton->signal_clicked().connect( sigc::mem_fun(*this, &DerivedDialog::on_button_quit) );
      }
    }

    DerivedDialog::~DerivedDialog()
    {
    }

    void DerivedDialog::on_button_quit()
    {
      hide(); //hide() will cause main::run() to end.
    }

Accessing widgets |  | Chapter 27. Internationalization and Localization