1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="highlight.min.css">
<script src="highlight.min.js"></script><script>
hljs.configure({languages: ['cpp']});
hljs.highlightAll();
</script><title>Accessing widgets</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="Programming with gtkmm 4">
<link rel="up" href="chapter-builder.html" title="Chapter 26. Gtk::Builder">
<link rel="prev" href="chapter-builder.html" title="Chapter 26. Gtk::Builder">
<link rel="next" href="sec-builder-using-derived-widgets.html" title="Using derived widgets">
</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">Accessing widgets</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="chapter-builder.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<th width="60%" align="center">Chapter 26. Gtk::Builder</th>
<td width="20%" align="right"> <a accesskey="n" href="sec-builder-using-derived-widgets.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="sec-builder-accessing-widgets"></a>Accessing widgets</h2></div></div></div>
<p>
To access a widget, for instance to show a dialog, use
the <code class="methodname">get_widget()</code> method, providing the widget's name.
This name should be specified in the <span class="application">Cambalache</span>
window. If the widget could not be found, or is of the wrong type, then the
pointer will be set to <code class="literal">nullptr</code>.
</p>
<p>
The dialogs in this chapter are derived from <code class="classname">Gtk::Window</code>
because <code class="classname">Gtk::Dialog</code> is deprecated since <span class="application">gtkmm</span> 4.10.
</p>
<pre class="programlisting"><code class="code">auto pDialog = builder->get_widget<Gtk::Window>("DialogBasic");
</code></pre>
<p>
<code class="classname">Gtk::Builder</code> 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.
</p>
<p>
Remember that you are not instantiating a widget with
<code class="methodname">get_widget()</code>, you are just obtaining a pointer to one that
already exists. You will always receive a pointer to the same instance when you
call <code class="methodname">get_widget()</code> on the same
<code class="classname">Gtk::Builder</code>, with the same widget name. The
widgets are instantiated during <code class="methodname">Gtk::Builder::create_from_file()</code>.
</p>
<p>
<code class="methodname">get_widget()</code> returns child widgets that are
<code class="function">manage()</code>ed (see the <a class="link" href="chapter-memory.html" title="Chapter 25. Memory management">Memory
Management</a> chapter), so they will be deleted when their parent
container is deleted. <code class="classname">Window</code>s (such as <code class="classname">Dialog</code>s)
cannot be managed because they have no parent container, so you must delete them at
some point. The documentation of <code class="classname">Gtk::Builder</code> has more to say
about the memory management of different kinds of objects.
</p>
<p><a class="ulink" href="https://gnome.pages.gitlab.gnome.org/gtkmm/classGtk_1_1Builder.html" target="_top">Reference</a></p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="builder-example-basic"></a>Example</h3></div></div></div>
<p>
This simple example shows how to load a <code class="filename">.ui</code>
file at runtime and access the widgets with <code class="classname">Gtk::Builder</code>.
</p>
<p><a class="ulink" href="https://gitlab.gnome.org/GNOME/gtkmm-documentation/tree/master/examples/book/builder/basic" target="_top">Source Code</a></p>
<p>File: <code class="filename">main.cc</code> (For use with gtkmm 4)</p>
<pre class="programlisting"><code class="code">#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);
}
</code></pre>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="chapter-builder.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="sec-builder-using-derived-widgets.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 26. Gtk::Builder </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"> Using derived widgets</td>
</tr>
</table>
</div>
</body>
</html>
|