Create  Edit  FrontPage  Index  Search  Changes  History  RSS  Login

tut-gtk2-dynui-bui

Building Example UI With Glade

As announced at the end of previous page, in continuation you are going to be creating a simple file browser application with Glade and Libglade. You begin by creating a new project with "File -> New" or by using an empty project created for you when you start-up the Glade application. You can also open an existing project with "File -> Open" by opening a file with ".glade" extension.

Creating the Window


glade-fig-10-03-window-mesh.png

After you have a blank project, you can begin by creating a new top-level Gtk::Window (note that in Glade double colons are omitted). In the new window you will see a mesh pattern in the interior of the widget. The mash pattern is indicating that the widget is a container into which you can place a child widget. You place a child widget into such an area by selecting a non-top-level widget from the widget palette and then clicking this mesh area. Note that all container widgets contain mash areas. Later on in this session we will also see how to change a button into a container to hold a label and an image.

After you create the top-level window, you will notice changes in the content of the widget Properties window. In this window you can customize all of the properties of each widget that is supported in Glade. The widget property window contains five tabs filled with various options.


glade-fig-10-04-prop-dialog.png

The General tab provides basic options that are specific to the widget type that is currently selected. For example, the GtkWindow widget allows you to specify the window's type (Top Level, or Pop-Up), title, ability to be resized, default size, etc. The Name field is used to give a unique name to the widget. Glade will automatically assign a name to each widget that is unique for the current project, but these are generic names. If you plan to refer to a widget from within your application, you should give it a name that means something.

The Packing tab provides basic information about how the widget will react to the changes in the size of its parent widget, such as expanding and filling. Common properties are those provided by Gtk::Widget and are available to all widgets. For example you can provide a size request in this tab.

Note:
Packing options are a bit unique when first working with Glade, because properties are set by the child instead of the parent container. For example, packing options for the children of a Gtk::VBox will be provided in the Packing tab of the children themselves instead of the parent container.

The Signals tab allows you to define signals for each widget that will be connected by Libglade. Lastly the Accessibility tab gives the options that are used for accessibility support.

As you know an empty Gtk::Window is of no use. Since our file browser will need multiple widgets packed one above the other into the main window, the next step will be to add into our window a vertical box container. Select the Vertical Box widget from the palette's container section and click on the mesh area of the window. You will be presented with the dialogue, like the one the left here, asking you how many items (rows in this case) your Gtk::VBox will hold.

glade-fig-10-05-vbox-dialog.png

By default three cells are allocated to hold three children widgets, but you can change this value to any number of widgets your application requires. For our file browser application three is exactly what we need at the moment, so go ahead and press OK.


Note:
Do not worry if you are not sure how many widgets the container will hold. You can add or remove cells in the General tab in the widget Property window. You can change the position of a widget within a box under the Packing tab and you are also able to edit the user interface with your code after it is built by Libglade.

After adding the vertical box, you will see three separate empty container meshes; notice the changes in the Properties window and the widget tree view. To these meshes, we will be adding (1) a toolbar, (2) an address bar, and (3) a tree view.

Adding a Toolbar

It is usually a good idea when creating a toolbar to add it to a handle box so that the user can remove the toolbar from the window if desired. To do this you need to select the Handle Box item from the widget palette, and then click the topmost Gtk::VBox cell. Finally you add the toolbar widget to the handle box.

glade-fig-10-05-toolbNedit.png

When the toolbar widget is placed into the top cell (mesh) if you carefully looked at the Glade menu, you would notice that the Edit button appeared (see the image on the right). Clicking this button, or right-clickinh the toolbar item in the widget tree view above the properties, will open the toolbar editor.

glade-fig-10-05-toolbeditor.png

This editor helps us create new tool items that compose the toolbar. You will have to add all the items by clicking on he Add button. This process is rather involved for a novice Glade user, and requires you to specify the type of the item you are adding, define any adornments like Stock items and most importantly define the Signal handlers.

In Glade you only define the names and signals that handlers will handle. This is what we will do shortly, however this is only the first step, namely, after your user interface will be created and you will run it through Libglade which will temporarily create dummy signal handlers for you, you will still have to implement the desired functionality for all these signal handlers in your code. So we have a lot to learn here. But not to worry, we will do it gradually, so let us role up our sleeves and start with the first step in Glade and toolbar editor.

Our toolbar will contain 9 items, 7 buttons and 2 separators. The first two buttons will be of type Menu which create button of type Gtk::MenuToolButton with a little arrow beside it which allows to associate with it a popup menu (see session "Toolbar Items" in chapter Menus and Toolbars). The other five buttons on this toolbar will be regular buttons. Following table lists all nine items for our toolbar (note items 3 and 7 marked as "S" are separators:

.         1.    2.      3. 4.      5.       6.     7. 8.      9.
-------------------------------------------------------------------------
Name:     back  forward S  up      refresh  home   S  delete  info
-------------------------------------------------------------------------
Type:     Menu  Menu    S  Button  Button   Button S  Button  Button
-------------------------------------------------------------------------
ImgTyp:   Stock Stock   /  Stock   Stock    Stock  /  Stock   Stock
-------------------------------------------------------------------------
StkImg:   Back  Forward /  Up      Refresh  Home   /  Delete  Information
Note:
You will see Edit button on the Glade menu only when a Tool Bar or a Menu Bar in the widget tree is selected - highlighted. (We will talk about Menu Bars at the end of this session.)

We have already mentioned that when you click Edit button on the main menu of our Glade application, an empty toolbar editor window opens (see the last image above). To add items to the menu bar you must click the Add button. The following window appears:

glade-fig-10-05-toolbeditor-add.png

This window has three parts left (current item list), right (current item properties) and the bottom (current item signal handling). Every time you press the Add button on the left you add a new item to the list. When an item is selected it is highlighted and you can change its properties on the right side of the window and signal handling part at the bottom. Looking at our list of nine items the name (black) is the first thing you will enter. For this item you will change the "Type" to "Menu". The next entry "Image Type" should stay as is (Stock), and in Stock Item you should select the image called "Back". This concludes the right side (specification of current item's properties). We would normally continue to the bottom part now and enter the relevant info for the callback. However you can discontinue entering at any time by clicking "Close" button in the toolbar editor. If you do so, do not forget to also click "Save" on the main menu of Glade application window. To continue with the "toolbar editor" you need to highlight (select) the toolbar item in the widget tree and click "Edit". You can continue adding additional items ignoring the signals for now, since changes and additions can be made at any time.

But we still need to learn how to enter the signal handler part. Actually Glade helps us here too, it suggests the name for the callback. The name it suggests is built from three parts: "on_" + "item-name" + "_signal". So for buttons we create the suggested names will be:

Glade suggested names for our callbacks:
  • on_back_clicked
  • on_forward_clicked
  • on_up_clicked
  • on_refresh_clicked
  • on_home_clicked
  • on_delete_clicked
  • on_info_clicked

Now all you need to learn is to figure out how to find out where this is done. If you look at the bottom part of the "toolbar editor" window below the Add and Remove buttons you will see the heading: "Signal | Handler | User data | After". You need to select (highlight) an item from the left side in the item list. Depending on the type of the selected item different categories of signals may appear. They are as follows:

Categories of Signals:

In this session we are only concerned about the Gtk::ToolButton's clicked signal. Each signal line in the "toolbar editor" has expander triangle. Make sure your "GtkToolButton" is expanded and you see the "clicked" signal underneath. Highlight the "clicked line". On the right you will see two strings reading "<Type here>". Click on the first one under the heading "Handler". A screen similar to the following will appear:

glade-fig-10-05-toolbeditor-inwks-1ed.png

In the entry field only click letter "o". This will give you the suggested name for the callback on the currently selected tool item. Repeat this for all the items you have entered so far. Verify your items that they have registered all the callbacks you think you've just created. Glade is sometimes very critical of what you are doing and may not always agree with your actions! When you are done, after clicking close in the "toolbar editor", make sure you save the changes in the main Glade window.

Following is the image only after a few toolbar items have been entered. Pay attention to the way toolbar is rendered here. It takes more space than it will when we are done, and that is a feature managed by the items on the packing tab.

glade-fig-10-05-toolbeditor-inwks-2win.png

When you are finished editing the toolbar, you will notice that the handle box always takes up exactly one third of the window vertically because, by default, widgets are set to expanded and fill(ed). You will want to unset the expanded property of the handle box, as shown in the following figure:

glade-fig-10-05-toolbeditor-inwks-3ed.png

Tip:
Glade is a perfect opportunity for you to experiment with packing options to gain better understanding of how they affect the widget.

The packing tab also includes options to determine padding around the widget, whether the packing is from the start or from the end of the box, and to determine the widget's position within the container. These properties are exactly the same as those you use when adding children widgets to the Gtk::Box with Gtk::Box#pack_start and related instance methods.

Completing the File Browser

glade-fig-10-9-toolbeditor-addrbar-1.png

The next step in creating our file browser is to create the address bar that will show the users the current location and allow them to enter a new location. This means that we need (1) a horizontal box with three cells, (1.a) first for a label describing the content held in (1.b) the second cell in Gtk::Entry widget, and (1.c) the last cell holding the button that will move to the location when pressed. You should have no trouble placing these items { (1), (1.a), (1.b) and (1.c) } into the second cell underneath the toolbar we just created in the vertical box. For our fourth item (1.c), we could easily just use the Gtk::Stock::JUMP stock item, but instead we will learn how to turn a button into a container. In order to do that you first need to change the button type to a container in the Properties dialogue. This will display an empty container mesh as the content of the button. Next we will add a horizontal box with two cells one for the image (Gtk::Stock::JUMP_TO) and the other for the label "Go". Yet another interesting thing to note is the use of Pango Text Markup with our label. To activate markup feature you need to set it in the Properties for the label widget.

The next step in creating our file browser is to create the address bar that will show the users the current location and allow them to enter a new location. This means that we need (1) a horizontal box with three cells, (1.a) first for a label describing the content held in (1.b) the second cell in Gtk::Entry widget, and (1.c) the last cell holding the button that will move to the location when pressed. You should have no trouble placing these items { (1), (1.a), (1.b) and (1.c) } into the second cell underneath the toolbar we just created in the vertical box. For our fourth item (1.c), we could easily just use the Gtk::Stock::JUMP stock item, but instead we will learn how to turn a button into a container. In order to do that you first need to change the button type to a container in the Properties dialogue. This will display an empty container mesh as the content of the button. Next we will add a horizontal box with two cells one for the image (Gtk::Stock::JUMP_TO) and the other for the label "Go". Yet another interesting thing to note is the use of Pango Text Markup with our label. To activate markup feature you need to set it in the Properties for the label widget. You may also activate mnemonics by setting the property "Use underline" just underneath the "Use markup" property.

The remaining step here is to add a Gtk::ScrolledWindow widget to the last (third) cell in the vertical box and the Gtk::TreeView to that container. On the following figure you can see the result of our work so far:

glade-fig-10-11-toolbeditor-browser-1.png

Making Changes

The file browser is completely designed, but now we would like to add a status bar widget at the bottom of the window. With Glade it is easy to make simple changes like this. We first have to extend the parent widget to have an additional cell. Obviously we need to add a cell to the vertical box, holding our toolbar, address bar and the scrolled text view. To do this , select the vertical box from the widget tree view. In the Properties window in General tab you should increase the "Number of items" property. This will open a new cell with mesh in it at the bottom. You can now add a status bar widget located in the "Control and Display" section of the Palette to the new empty container. If you need to reorder the children of a vertical or horizontal box, you first need to select the widget you want to move, and then under the Packing tab in the Property pane advance it to the appropriate position by altering the value of the Position spin button. The position of the surrounding widgets will be automatically adjusted, and you can observe the changes on the canvas, where the changes are immediately reflected in your creation.

Another complication may result if you decided that you needed to insert an existing widget into another more elaborate container. For instance, you may want to place the scrolled tree view into a horizontal pane to share the space with another vertical box. In order to do that you first need to select the widget (scrolled window in our case) from the widget tree view in the main window and remove it by "cutting it out" with <Ctrl+X>, which will display an empty cell with mesh in it. Now you can add a horizontal pane, and finally place (paste) the scrolled window from the clipboard into the appropriate place in the horizontal pane by pressing <Ctrl+V> or by right-clicking "Paste".

Making changes used to be a touchy topics with Glade 2, because it did not support undo and redo actions. Namely, during making changes it is very easy to make a mistake and if there is no way to back out this could spell a disaster. Regardless of how secure is a tool it is prudent to use project Save button as often as possible.

Widget Signals

glade-fig-10-12-gobtt-signal.png

The last step for this application is to set up signals for all of the widgets. The image on the left shows the Signals tab of the widget properties editor for the Go button. The Gtk::Button widget is connected to the clicked signal, which will call on_go_clicked callback when emitted.

In addition to the "clicked" signal, you need to connect to few others. We have already discussed the tool items and their signal handling options, where as we know each of the tool items, with the exception of the separators, is connected to the Gtk::ToolButton's "clicked" signal.

Also you should connect the Gtk::Entry widget to "activate" signal, which will be emitted when the user presses the Enter key as entry has focus.

As for the tree view, you should connect it to "row-activated" signal which will callon_treeview_row_activated callback.


Creating a Menu

In addition to toolbars, it is possible to create menus in Glade 3. When you add a menu bar container from the Palette to an empty cell it will activate the Edit button on the Glade's main Menu bar. Pressing it you will open A Menu Bar Editor which is very similar to the "toolbar editor". To add first level widgets is straight forward, however you may find it difficult to add an additional submenu. It is not impossible, but certainly needs to be simplified in the future. What you need to do is to copy <Ctrl+C> an existing menu item with a menu in it and paste <Ctrl+V> it into a desired place.

So far we have learnt, there exist three ways to create menus. Every method has its advantages and disadvantages. Let's look at each individual method.

You first learnt how to create menus manually, modelling each object to your needs. This method is good enough for smaller menus. because the code will not take up a lot of space and the implementation is located located entirely in one place. However, if your menu grows in size or contains more than just basic items, the code will become tedious to maintain and will rapidly grow in size.

Next you learnt how to use Gtk::UIManager with UI definitions to dynamically create menus. This method simplified menu creation, because you could define a large number of actions in a small amount of space. Also, since menus are constructed from UI definitions, allowing the user to edit a menu is extremely simple. This is certainly the preferred method of menu creation if you are not using Glade to design your applications.

Glade also presents a very attractive method of menu creation, because after its initial design maintenance is simple. It also requires no code to create the menu, since Libglade constructs it for you. However, one problem with this method is that it is not as easy to allow the users to alter the layout of menus and toolbars as with the UI file method. You may need to resort to both Gtk::UIManager and Glade method in cases like this. However, if you do not need to allow your users to customize your menus , it makes sense to do all menu creation through Glade.

Last modified:2011/08/16 17:44:00
Keyword(s):
References:[tut-gtk] [tut-gtk2-dynui]