|
| 1 | +.. _ui_glade: |
| 2 | + |
| 3 | +Glade user interface designer |
| 4 | +============================= |
| 5 | + |
| 6 | +Glade is a rapid-application-development program (RAD) or graphical user-interface-builder, that allows the easy creation of Gtk-applications. The user interface is stored in an XML-file (file extension: *".glade"*), which is called by the main program. The older version of Glade, 3.8.x, targets Gtk+ 2.x applications, while the newer 3.16.x, targets Gtk+ 3.x. |
| 7 | + |
| 8 | +.. _ui_glade_316_python3: |
| 9 | + |
| 10 | +Glade 3.16 example using Python 3 |
| 11 | +--------------------------------- |
| 12 | +This example uses Glade 3.16.x and Python 3.x. In order to understand the code it is recommended to work through the Python-GtK3-Tutorial: http://python-gtk-3-tutorial.readthedocs.org/en/latest/. |
| 13 | + |
| 14 | +The first step is to start Glade and open a new project. Drag a *GtkApplicationWindow* into the work area. In the bottom-right menu you can change the default name from *"applicationwindow1"* to *"window1"*. This is the designation that the window will have in the Python 3 code and in Glade for certain actions. In the *Signals* tab of the same menu open the *GtkWidget* tree and find the *destroy* entry. This is the widget that will allow you to connect the program with the close-button of the window. Enter the action *"on_window1_destroy"* (window1 being the name we gave this window). |
| 15 | + |
| 16 | +In the next step we need to create a container to place the Matplotlib-widget. This tutorial uses a *GtkScrolledWindow*, which you can drag-and-drop on the *GtkApplicationWindow*. Now we are going to save the Glade file into directory with the name *"mpl_with_glade_316.glade"*. Note that there are many options in Glade you can additionally set like the default size of the window. These options are fairly easy to set. |
| 17 | + |
| 18 | +.. figure:: ../_static/mpl_with_glade_1.png |
| 19 | + :width: 50 % |
| 20 | + :alt: Figure of the Glade interface, highlighting some steps in the interface. |
| 21 | + :align: left |
| 22 | + |
| 23 | + **Figure 1:** First steps of designing a simple user interface in Glade. Allow the window to be closed (a). The GtkScrolledWindow button (b) has to be placed on the main window (c). |
| 24 | + |
| 25 | +The code of the finished example will look something like this: |
| 26 | + |
| 27 | +:: |
| 28 | + |
| 29 | + <?xml version="1.0" encoding="UTF-8"?> |
| 30 | + <!-- Generated with glade 3.16.1 --> |
| 31 | + <interface> |
| 32 | + <requires lib="gtk+" version="3.10"/> |
| 33 | + <object class="GtkApplicationWindow" id="window1"> |
| 34 | + <property name="can_focus">False</property> |
| 35 | + <property name="title" translatable="yes">Matplotlib</property> |
| 36 | + <property name="default_width">800</property> |
| 37 | + <property name="default_height">600</property> |
| 38 | + <signal name="destroy" handler="on_window1_destroy" swapped="no"/> |
| 39 | + <child> |
| 40 | + <object class="GtkScrolledWindow" id="scrolledwindow1"> |
| 41 | + <property name="visible">True</property> |
| 42 | + <property name="can_focus">True</property> |
| 43 | + <property name="border_width">10</property> |
| 44 | + <property name="shadow_type">in</property> |
| 45 | + <child> |
| 46 | + <placeholder/> |
| 47 | + </child> |
| 48 | + </object> |
| 49 | + </child> |
| 50 | + </object> |
| 51 | + </interface> |
| 52 | + |
| 53 | +The Python 3 file that executes the program can look like this: |
| 54 | + |
| 55 | +:: |
| 56 | + |
| 57 | + #!/usr/bin/env python3 |
| 58 | + |
| 59 | + from gi.repository import Gtk, Gio |
| 60 | + |
| 61 | + from matplotlib.figure import Figure |
| 62 | + from matplotlib.axes import Subplot |
| 63 | + from numpy import arange, sin, pi |
| 64 | + from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas |
| 65 | + |
| 66 | + import sys |
| 67 | + |
| 68 | + class Window1Signals: |
| 69 | + def on_window1_destroy(self, widget): |
| 70 | + Gtk.main_quit() |
| 71 | + |
| 72 | + def main(): |
| 73 | + builder = Gtk.Builder() |
| 74 | + builder.add_objects_from_file("mpl_with_glade_316.glade", ("window1", "") ) |
| 75 | + builder.connect_signals(Window1Signals()) |
| 76 | + window = builder.get_object("window1") |
| 77 | + sw = builder.get_object("scrolledwindow1") |
| 78 | + |
| 79 | + #Start of Matplotlib specific code |
| 80 | + figure = Figure(figsize=(8,6), dpi=71) |
| 81 | + axis = figure.add_subplot(111) |
| 82 | + t = arange(0.0, 3.0, 0.01) |
| 83 | + s = sin(2*pi*t) |
| 84 | + axis.plot(t,s) |
| 85 | + |
| 86 | + axis.set_xlabel('time [s]') |
| 87 | + axis.set_ylabel('voltage [V]') |
| 88 | + |
| 89 | + canvas = FigureCanvas(figure) # a Gtk.DrawingArea |
| 90 | + canvas.set_size_request(800,600) |
| 91 | + sw.add_with_viewport(canvas) |
| 92 | + #End of Matplotlib specific code |
| 93 | + |
| 94 | + window.show_all() |
| 95 | + Gtk.main() |
| 96 | + |
| 97 | + if __name__ == "__main__": |
| 98 | + main() |
| 99 | + |
| 100 | +Notice that we defined a function *"the on_window1_destroy"* that we named in Glade. This function ensures that closing the window will quit the Gtk-application. The *GtkScrolledWindow* is first connected through the *Gtk.Builder*, then the Matplotlib-plot is placed in a *FigureCanvas* and this canvas is then added to the *GtkScrolledWindow*. |
| 101 | + |
| 102 | +You can also add the *Matplotlib-NavigationToolbar* to the example. This requires a division of the screen into two scrolled windows (See **Figure 2**). |
| 103 | + |
| 104 | +.. figure:: ../_static/mpl_with_glade_2.png |
| 105 | + :width: 50 % |
| 106 | + :alt: Figure of the Glade interface, showing how to divide the window into 2 scrolled windows. |
| 107 | + :align: left |
| 108 | + |
| 109 | + **Figure 2:** The interface for this example consists of a *GtkApplicationWindow* which is divided into 2 rows using a *GtkBox*. A *GtkScrolledWindow* is placed in both cells (See tree view in upper-right corner). |
| 110 | + |
| 111 | +The new Glade-code: |
| 112 | + |
| 113 | +:: |
| 114 | + |
| 115 | + <?xml version="1.0" encoding="UTF-8"?> |
| 116 | + <!-- Generated with glade 3.16.1 --> |
| 117 | + <interface> |
| 118 | + <requires lib="gtk+" version="3.10"/> |
| 119 | + <object class="GtkApplicationWindow" id="window1"> |
| 120 | + <property name="can_focus">False</property> |
| 121 | + <property name="title" translatable="yes">Matplotlib</property> |
| 122 | + <property name="default_width">800</property> |
| 123 | + <property name="default_height">600</property> |
| 124 | + <signal name="destroy" handler="on_window1_destroy" swapped="no"/> |
| 125 | + <child> |
| 126 | + <object class="GtkBox" id="box2"> |
| 127 | + <property name="visible">True</property> |
| 128 | + <property name="can_focus">False</property> |
| 129 | + <property name="orientation">vertical</property> |
| 130 | + <child> |
| 131 | + <object class="GtkScrolledWindow" id="scrolledwindow1"> |
| 132 | + <property name="width_request">700</property> |
| 133 | + <property name="height_request">600</property> |
| 134 | + <property name="visible">True</property> |
| 135 | + <property name="can_focus">True</property> |
| 136 | + <property name="border_width">10</property> |
| 137 | + <property name="shadow_type">in</property> |
| 138 | + <child> |
| 139 | + <placeholder/> |
| 140 | + </child> |
| 141 | + </object> |
| 142 | + <packing> |
| 143 | + <property name="expand">False</property> |
| 144 | + <property name="fill">True</property> |
| 145 | + <property name="position">0</property> |
| 146 | + </packing> |
| 147 | + </child> |
| 148 | + <child> |
| 149 | + <object class="GtkScrolledWindow" id="scrolledwindow2"> |
| 150 | + <property name="visible">True</property> |
| 151 | + <property name="can_focus">True</property> |
| 152 | + <property name="border_width">10</property> |
| 153 | + <property name="shadow_type">in</property> |
| 154 | + <child> |
| 155 | + <placeholder/> |
| 156 | + </child> |
| 157 | + </object> |
| 158 | + <packing> |
| 159 | + <property name="expand">False</property> |
| 160 | + <property name="fill">True</property> |
| 161 | + <property name="position">1</property> |
| 162 | + </packing> |
| 163 | + </child> |
| 164 | + </object> |
| 165 | + </child> |
| 166 | + </object> |
| 167 | + </interface> |
| 168 | + |
| 169 | +The new Pyhton code: |
| 170 | + |
| 171 | +:: |
| 172 | + |
| 173 | + #!/usr/bin/env python3 |
| 174 | + |
| 175 | + from gi.repository import Gtk, Gio |
| 176 | + |
| 177 | + from matplotlib.figure import Figure |
| 178 | + from matplotlib.axes import Subplot |
| 179 | + from numpy import arange, sin, pi |
| 180 | + from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas |
| 181 | + from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar |
| 182 | + |
| 183 | + import sys |
| 184 | + |
| 185 | + class Window1Signals: |
| 186 | + def on_window1_destroy(self, widget): |
| 187 | + Gtk.main_quit() |
| 188 | + |
| 189 | + def main(): |
| 190 | + builder = Gtk.Builder() |
| 191 | + builder.add_objects_from_file("mpl_with_glade_316_navigationtoolbar.glade", ("window1", "") ) |
| 192 | + builder.connect_signals(Window1Signals()) |
| 193 | + window = builder.get_object("window1") |
| 194 | + sw1 = builder.get_object("scrolledwindow1") |
| 195 | + sw2 = builder.get_object("scrolledwindow2") |
| 196 | + |
| 197 | + #Start of Matplotlib specific code |
| 198 | + figure = Figure(figsize=(4,3), dpi=71) |
| 199 | + axis = figure.add_subplot(111) |
| 200 | + t = arange(0.0, 3.0, 0.01) |
| 201 | + s = sin(2*pi*t) |
| 202 | + axis.plot(t,s) |
| 203 | + |
| 204 | + axis.set_xlabel('time [s]') |
| 205 | + axis.set_ylabel('voltage [V]') |
| 206 | + |
| 207 | + canvas = FigureCanvas(figure) |
| 208 | + sw1.add_with_viewport(canvas) |
| 209 | + |
| 210 | + toolbar = NavigationToolbar(canvas, window) |
| 211 | + sw2.add_with_viewport(toolbar) |
| 212 | + #End of Matplotlib specific code |
| 213 | + |
| 214 | + window.show_all() |
| 215 | + Gtk.main() |
| 216 | + |
| 217 | + if __name__ == "__main__": |
| 218 | + main() |
| 219 | + |
| 220 | +The finished second example is shown in **Figure 3**. |
| 221 | + |
| 222 | +.. figure:: ../_static/mpl_with_glade_3.png |
| 223 | + :width: 50 % |
| 224 | + :alt: Figure of the Glade interface, showing how to divide the window into 2 scrolled windows. |
| 225 | + :align: left |
| 226 | + |
| 227 | + **Figure 3:** The finished program (shown here in Ubuntu 14.04). |
0 commit comments