Designing the GUI using Glade is straightforward. Just start the Glade program and you will see this interface (from macOS, or something similar if using another OS):
Let's now explore the Glade interface. There are four main buttons that we will be using primarily in Glade; Toplevels, Containers, Control, and Display. The preceding screenshot shows that GtkWindow is listed in Toplevels, which serves as the basic unit for construction. Let's click on GtkWindow and see the resulting action:
Now a GtkWindow is being constructed and nothing is inside. Let's set the size of this GtkWindow to: 400x400. This can be achieved by setting the default width and height as 400 in the lower section of the right panel. The right panel is currently illustrating the General properties of this GtkWindow.
Remember that we used vertical boxes a lot in the previous examples? Let's add a vertical box to the GtkWindow! This can be achieved by clicking on Containers and choosing GtkBox, as shown here:
After choosing GtkBox, click on the GtkWindow in the middle panel and a GtkBox will be created as a sub-module or a sub-window of the GtkWindow. This can be confirmed by checking the left panel as shown here:
GtkBox is below GtkWindow and indented on the left panel. Since we are picking vertical box, the orientation in General is vertical. One can even specify the spacing and number of items that will be included in the GtkBox. Let's add a menu bar onto the top vertical box. This can be done as shown in Figure 9. In Containers, pick GtkMenubar and click on the top vertical box. It will fit in a menu bar with the following options: File, Edit, View, and Help.
As one can imagine, we can easily design our favorite GUI with the use of Glade. We can import a label with a customized size as shown in Figure 10. And there are many more options that we can choose to customize our GUIs.
Designing the most effective GUI through Glade is beyond the scope and purview of this book, so we will not go any further into the more advanced options in Glade.
However, we would like to expand on one of the examples that we have worked on previously, and show that it takes just a few lines of code to incorporate a Glade-based GUI into our workflow.
To begin, we will use the class-based polar plot example. First of all, we design the most basic GtkWindow with a size of 400x400 (that's all!) from Glade and save it as a file.
The file is very simple and self-explanatory:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<property name="default_width">400</property>
<property name="default_height">400</property>
<signal name="destroy" handler="on_window1_destroy" swapped="no"/>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
Readers may understand that we just created a GtkWindow with a size of 400x400 plus a child as GtkScrolledWindow. This can be completed in a few clicks in Glade.
And what we have to do now is use Gtk.Builder() to read the Glade file; everything will be constructed automatically. This actually saves us from defining all the elements of the vertical box!
#Same old, importing Gtk module, we are also importing some other stuff this time
#such as numpy and the backends of matplotlib
import gi, numpy as np, matplotlib.cm as cm
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from matplotlib.figure import Figure
from numpy import arange, pi, random, linspace
import matplotlib.cm as cm
#Possibly this rendering backend is broken currently
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
#New class, here is to invoke Gtk.main_quit() when the window is being destroyed
#Necessary to quit the Gtk.main()
class Signals:
def on_window1_destroy(self, widget):
Gtk.main_quit()
class MatplotlibEmbed(Gtk.Window):
#Instantiation, we just need the canvas to store the figure!
def __init__(self):
#Readers should find it familiar, as we are creating a matplotlib figure here with a dpi(resolution) 100
self.fig = Figure(figsize=(5,5), dpi=100)
#The axes element, here we indicate we are creating 1x1 grid and putting the subplot in the only cell
#Also we are creating a polar plot, therefore we set projection as 'polar
self.ax = self.fig.add_subplot(111, projection='polar')
#Here, we borrow one example shown in the matplotlib gtk3 cookbook
#and show a beautiful bar plot on a circular coordinate system
self.theta = linspace(0.0, 2 * pi, 30, endpoint=False)
self.radii = 10 * random.rand(30)
self.width = pi / 4 * random.rand(30)
self.bars = self.ax.bar(self.theta, self.radii, width=self.width, bottom=0.0)
#Here defines the color of the bar, as well as setting it to be transparent
for r, bar in zip(self.radii, self.bars):
bar.set_facecolor(cm.jet(r / 10.))
bar.set_alpha(0.5)
#Here we generate the figure
self.ax.plot()
#Creating Canvas which store the matplotlib figure
self.canvas = FigureCanvas(self.fig) # a Gtk.DrawingArea
#Here is the magic, we create a GTKBuilder that reads textual description of a user interface
#and instantiates the described objects
builder = Gtk.Builder()
#We ask the GTKBuilder to read the file and parse the information there
builder.add_objects_from_file('/Users/aldrinyim/Dropbox/Matplotlib for Developer/Jupyter notebook/ch05/window1_glade.glade', ('window1', '') )
#And we connect the terminating signals with Gtk.main_quit()
builder.connect_signals(Signals())
#We create the first object window1
window1 = builder.get_object('window1')
#We create the second object scrollwindow
scrolledwindow1 = builder.get_object('scrolledwindow1')
#Instantiate the object and start the drawing!
polar_drawing = MatplotlibEmbed()
#Add the canvas to the scrolledwindow1 object
scrolledwindow1.add(polar_drawing.canvas)
#Show all and keep the Gtk.main() active!
window1.show_all()
Gtk.main()
The preceding code demonstrates how we can use Glade to quickly generate a frame and execute it effortlessly.
Hopefully, through this example readers would appreciate the power of Glade in enabling programmers to draw a GUI instead of abstracting it in code. This is particularly useful when the GUI gets complicated.