## 2.7 UI Delegates

The UI Delegate classes, located in the `kiwi.ui.delegates` module, use multiple inheritance, being derived from both a View and a Controller. This means they combine functionality from both into a single class: not only does it specify the interface, it also handles the widget signals. It's the "can't beat them, join them" solution to the V+C coupling problem, and it's used in Swing, MFC and Bakery, a C++ framework for GTK+.

The `Delegate` class is a combination of `BaseView` and `BaseController`. You can use it to create your interface programatically and then hook up handlers to it, just like you would do to individual views and controllers. A very simple (yes, I too get bored of hand-coding PyGTK widgets) example follows, found in the distribution as examples/framework/simple.py:

    #!/usr/bin/env python
    import gtk

    from kiwi.ui.delegates import Delegate

    class Hello(Delegate):
        def __init__(self):
            self.index = 0
            self.text = ["I've decided to take my work back underground",
                         "To keep it from falling into the wrong hands."]

            topwidget = gtk.Window()
            topwidget.set_title("So...")
            self.button = gtk.Button(self.text[self.index])
            self.button.show()
            topwidget.add(self.button)

            Delegate.__init__(self, topwidget, delete_handler=gtk.main_quit)
            # focus button, our only widget
            self.focus_topmost()

        def on_button__clicked(self, button):
            self.index = self.index + 1

            # Two clicks and we're gone
            if self.index > 1:
                self.hide_and_quit()
                # the *handler's* return value disappears into GTK+
                return

            # update the label of the button
            button.set_label(self.text[self.index])

    app = Hello()
    app.show_and_loop()

As you can see, the Delegate was the only class we needed to inherit from and instantiate. This makes the amount of infrastructure code go down significantly, and most single-window applications (and individual dialogs in multi-window applications) can be implemented with single Delegate and GladeDelegate subclasses. As an example for using the GladeDelegate, below is a third version of our temperature conversion application, examples/Faren/faren3.py:

    #!/usr/bin/env python
    import gtk

    from kiwi.ui.delegates import Delegate

    class Farenheit(Delegate):
        widgets = ["quitbutton", "temperature", "celsius", "farenheit",
                   "celsius_label" , "farenheit_label", "temperature_label"]
        gladefile = "faren"
        def __init__(self):
            Delegate.__init__(self, delete_handler=self.quit_if_last)

        def convert_temperature(self, temp):
            farenheit = (temp * 9/5.0) + 32
            celsius = (temp - 32) * 5/9.0
            return farenheit, celsius

        def clear_temperature(self):
            self.farenheit.set_text("")
            self.celsius.set_text("")

        # Signal handlers

        def on_quitbutton__clicked(self, *args):
            self.hide_and_quit()

        def after_temperature__changed(self, entry, *args):
            temp = entry.get_text().strip() or None
            if temp is None:
                self.clear_temperature()
            else:
                try:
                    farenheit, celsius = self.convert_temperature(float(temp))
                except ValueError:
                    farenheit = celsius = float('nan')
                self.farenheit.set_text("%.2f" % farenheit)
                self.celsius.set_text("%.2f" % celsius)

    delegate = Farenheit()
    delegate.show()
    gtk.main()

As you can see, using the delegates makes a lot of sense in many cases: the view and controller split isn't essential, and you can end up with a lot less code with the same functionality at no reduced maintainability or readability, which is what we are aiming for. For larger applications, or apps where a lot of very unusual functionality is required, it may still make sense to use separate Controllers and Views, but for normal development, stick to delegates; they simplify things.

Note that there is also a `SlaveDelegate`, which works like a normal SlaveView with an attached Controller.