## 2.4 BaseView

Once you have written three (two?) applications using the PyGTK classes and commands directly, you get very bored of hand-coding the widgets and their structure. Sure, you have total control over them, and you can build them programatically, which is why you might want to do it for small parts of your application, but for anything that is medium to large-scale, having to maintain all that code makes changing the UI very painful. Damon Chaplin's application Glade provides a way to create a GTK+ interface visually, and it is normally used to generate C or C++ code that creates the widgets. It also saves the interface specification in an XML file. Knowing this, James Henstridge, the author of PyGTK, wrote libglade, a killer library (this was years ago, but I digress) that renders widgets based on specifications in an XML file. libglade allows you to keep the interface definition separate from the code, which is an awesome idea, since it drastically reduces the amount of interface code (and the consequent burden of maintaining it). Being able to use Glade to revisit and tweak your interface without having to regenerate code is also a huge advantage.

Anyway, Kiwi lets you use Glade interfaces in a very convenient manner, by using the `BaseView` class. Let's show this off by redoing the last example using glade. First thing would be running Glade and creating a window and putting a label into it. Name the window `hey` and turn the visible property off (using the Common tab of the Properties dialog). Save the file (careful with that Save dialog, it creates directories and is generally evil in my opinion) as hey.glade. And then code up `heyglade.py` (all this is available in examples/framework/hey/heyglade.py):

    #!/usr/bin/env python
    import gtk

    from kiwi.ui.gadgets import quit_if_last
    from kiwi.ui.views import BaseView

    app = BaseView(gladefile="hey", delete_handler=quit_if_last)
    app.show()
    gtk.main()

Oops. Where did all that code go? Right, we are now using the glade file to generate the UI. So we didn't even need to subclass `BaseView`; we just passed in a parameter that told it what glade file to use, and the same delete handler. Note also that we used `show_and_loop()` instead of `show_all_and_loop()`3.

The `gladefile` parameter indicates the file it should open. If the name you pass in doesn't have a .glade suffix, `BaseView` will append it and try to open it; in our cases, it will try to open the file hey.glade. However, this argument does a bit more than just specifying the file (when using this form of the constructor, which is simplified): it also specifies by default the name of the toplevel widget in the glade file. This is why I specifically stated the window should be named `hey` two paragraphs back. That widget is attached to the view instance with the name `toplevel`.

If you want to use another specific toplevel widget name, just use the extra constructor parameter `toplevel_name`. This can be useful if you have many windows in the same Glade file; you can reuse the glade file by just defining multiple `BaseView` instances (or subclass instances) with the same `gladefile` but specifying different toplevel widgets as each individual `toplevel_name`.

There are some common mistakes to be made when using the BaseView, and Kiwi raises special exceptions for three them.

1. The first one is forgetting to specify the gladefile, or giving it the wrong name. Kiwi will try to look for the file in its glade search path (which can be set by the GLADEPATH variable and also by using `Kiwi.Views.set_gladepath()`), and if it doesn't find it, it will complain with an `IOError` and stop.
2. The second is not having a widget with the name of the gladefile in your glade interface. This is only a mistake if you don't specify `toplevel_name`, of course. Kiwi raises an `AttributeError` here.
3. The third mistake is forgetting to make the window hidden. We want the window to be hidden to allow you to control when exactly it is shown, and if you use the same glade file for all your dialogs, you quickly will understand why. Kiwi prints a warning for this, as I don't consider it a fatal error.

To use `BaseView` effectively, it's important to define the `widgets` list, which defines what widgets are to be attached to your class. This list has its own semantics, which I discuss in the next section.

#### Footnotes

...show_all_and_loop()3
  It is important to note that BaseView does *not* allow you to call `show_all_and_loop()` -- you must use `show_and_loop()` instead. There is a reason for this. show_all means that all widgets under the toplevel widget should be shown; however in glade, since most widgets are visible by default, you only need to turn off visibility on the toplevel window to get the default hidden effect. This alone would not be a problem, but the fact is that certain widgets can be configured in glade to *require* being hidden (either because you want them initially hidden, or because they do something special, like the gtk.Toolbar: if you choose to use `Only Text' or `Only Icons', glade implements this by hiding the icons or text, respectively). This would break with show_all and too many bug reports told me it was enough reason to turn it off. You can of course call it manually on the window if you are really determined do so.