File: sec-builder-accessing-widgets.html

package info (click to toggle)
gtkmm-documentation 4.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,772 kB
  • sloc: cpp: 15,541; javascript: 1,208; makefile: 1,080; python: 401; xml: 106; perl: 67; sh: 8
file content (185 lines) | stat: -rw-r--r-- 7,189 bytes parent folder | download
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-&gt;get_widget&lt;Gtk::Window&gt;("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 &lt;gtkmm.h&gt;
#include &lt;iostream&gt;

namespace
{
Gtk::Window* pDialog = nullptr;
Glib::RefPtr&lt;Gtk::Application&gt; app;

void on_button_clicked()
{
  if (pDialog)
    pDialog-&gt;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-&gt;add_from_file("basic.ui");
  }
  catch(const Glib::FileError&amp; ex)
  {
    std::cerr &lt;&lt; "FileError: " &lt;&lt; ex.what() &lt;&lt; std::endl;
    return;
  }
  catch(const Glib::MarkupError&amp; ex)
  {
    std::cerr &lt;&lt; "MarkupError: " &lt;&lt; ex.what() &lt;&lt; std::endl;
    return;
  }
  catch(const Gtk::BuilderError&amp; ex)
  {
    std::cerr &lt;&lt; "BuilderError: " &lt;&lt; ex.what() &lt;&lt; std::endl;
    return;
  }

  // Get the GtkBuilder-instantiated dialog:
  pDialog = refBuilder-&gt;get_widget&lt;Gtk::Window&gt;("DialogBasic");
  if (!pDialog)
  {
    std::cerr &lt;&lt; "Could not get the dialog" &lt;&lt; std::endl;
    return;
  }

  // Get the GtkBuilder-instantiated button, and connect a signal handler:
  auto pButton = refBuilder-&gt;get_widget&lt;Gtk::Button&gt;("quit_button");
  if (pButton)
    pButton-&gt;signal_clicked().connect([] () { on_button_clicked(); });

  // It's not possible to delete widgets after app-&gt;run() has returned.
  // Delete the dialog with its child widgets before app-&gt;run() returns.
  pDialog-&gt;signal_hide().connect([] () { delete pDialog; });

  app-&gt;add_window(*pDialog);
  pDialog-&gt;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-&gt;register_application() explicitly, but
  // usually it's easier to let app-&gt;run() do it for you.
  app-&gt;signal_activate().connect([] () { on_app_activate(); });

  return app-&gt;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>