<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Using derived widgets</title> <link rel="stylesheet" href="style.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.75.1"> <link rel="home" href="index.html" title="Programming with gtkmm"> <link rel="up" href="chapter-builder.html" title="Chapter 23. Glade and Gtk::Builder"> <link rel="prev" href="sec-builder-accessing-widgets.html" title="Accessing widgets"> <link rel="next" href="chapter-internationalization.html" title="Chapter 24. Internationalization and Localization"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <div class="navheader"> <table width="100%" summary="Navigation header"> <tr><th colspan="3" align="center">Using derived widgets</th></tr> <tr> <td width="20%" align="left"> <a accesskey="p" href="sec-builder-accessing-widgets.html"><img src="icons/prev.png" alt="Prev"></a> </td> <th width="60%" align="center">Chapter 23. Glade and Gtk::Builder</th> <td width="20%" align="right"> <a accesskey="n" href="chapter-internationalization.html"><img src="icons/next.png" alt="Next"></a> </td> </tr> </table> <hr> </div> <div class="sect1" title="Using derived widgets"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="sec-builder-using-derived-widgets"></a>Using derived widgets</h2></div></div></div> <p> You can use <span class="application">Glade</span> to layout your own custom widgets derived from <span class="application">gtkmm</span> 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 <span class="application">Glade</span>, but you can specify its location and child widgets and the properties of its <span class="application">gtkmm</span> base class. </p> <p>Use <code class="methodname">Gtk::Builder::get_widget_derived()</code> like so: </p> <pre class="programlisting"> DerivedDialog* pDialog = 0; builder->get_widget_derived("DialogBasic", pDialog); </pre> <p> </p> <p> Your derived class must have a constructor that takes a pointer to the underlying C type, and the <code class="classname">Gtk::Builder</code> instance. All relevant classes of <span class="application">gtkmm</span> typedef their underlying C type as <code class="classname">BaseObjectType</code> (<code class="classname">Gtk::Dialog</code> typedefs <code class="classname">BaseObjectType</code> as <span class="type">GtkDialog</span>, for instance). </p> <p> You must call the base class's constructor in the initialization list, providing the C pointer. For instance, </p> <pre class="programlisting"> DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder) : Gtk::Dialog(cobject) { } </pre> <p> </p> <p> You could then encapsulate the manipulation of the child widgets in the constructor of the derived class, maybe using <code class="methodname">get_widget()</code> or <code class="methodname">get_widget_derived()</code> again. For instance, </p> <pre class="programlisting"> 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) ); } } </pre> <p> </p> <div class="sect2" title="Example"> <div class="titlepage"><div><div><h3 class="title"> <a name="builder-example-accessing"></a>Example</h3></div></div></div> <p> This example shows how to load a <span class="application">Glade</span> file at runtime and access the widgets via a derived class. </p> <p><a class="ulink" href="http://git.gnome.org/cgit/gtkmm-documentation/tree/examples/book/builder/derived" target="_top">Source Code</a></p> <p>File: <code class="filename">deriveddialog.h</code> </p> <pre class="programlisting"> #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 </pre> <p>File: <code class="filename">main.cc</code> </p> <pre class="programlisting"> #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(); #ifdef GLIBMM_EXCEPTIONS_ENABLED try { refBuilder->add_from_file("basic.ui"); } catch(const Glib::FileError& ex) { std::cerr << "FileError: " << ex.what() << std::endl; return 1; } catch(const Gtk::BuilderError& ex) { std::cerr << "BuilderError: " << ex.what() << std::endl; return 1; } #else std::auto_ptr<Glib::Error> error; if (!refBuilder->add_from_file("basic.ui", error)) { std::cerr << error->what() << std::endl; return 1; } #endif /* !GLIBMM_EXCEPTIONS_ENABLED */ //Get the GtkBuilder-instantiated dialog:: DerivedDialog* pDialog = 0; refBuilder->get_widget_derived("DialogBasic", pDialog); if(pDialog) { //Start: kit.run(*pDialog); } delete pDialog; return 0; } </pre> <p>File: <code class="filename">deriveddialog.cc</code> </p> <pre class="programlisting"> #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. } </pre> </div> </div> <div class="navfooter"> <hr> <table width="100%" summary="Navigation footer"> <tr> <td width="40%" align="left"> <a accesskey="p" href="sec-builder-accessing-widgets.html"><img src="icons/prev.png" alt="Prev"></a> </td> <td width="20%" align="center"><a accesskey="u" href="chapter-builder.html"><img src="icons/up.png" alt="Up"></a></td> <td width="40%" align="right"> <a accesskey="n" href="chapter-internationalization.html"><img src="icons/next.png" alt="Next"></a> </td> </tr> <tr> <td width="40%" align="left" valign="top">Accessing widgets </td> <td width="20%" align="center"><a accesskey="h" href="index.html"><img src="icons/home.png" alt="Home"></a></td> <td width="40%" align="right" valign="top"> Chapter 24. Internationalization and Localization</td> </tr> </table> </div> </body> </html>