I have searched Google and the web for a resource on creating Python new-style classes for windows and dialogs when using GTK’s Builder and Glade UI files. I haven’t found much, but have managed to piece together a workable model. The basics of the process is to create a new class that inherits from gtk.Window or gtk.Dialog. Override the __new__() method and retrieve the window object from builder, call a method to act like an __init__() method, and return the new window object.
The Window Class
#!/usr/bin/env python # -*- coding: utf-8 -*- import gtk, sys, os class MainWindow(gtk.Window): __gtype_name__ = "MainWindow" def __new__(cls): """This method creates and binds the builder window to class. In order for this to work correctly, the class of the main window in the Glade UI file must be the same as the name of this class.""" app_path = os.path.dirname(__file__) try: builder = gtk.Builder() builder.add_from_file(os.path.join(app_path, "main.ui")) except: print "Failed to load XML GUI file main.ui" sys.exit(1) new_object = builder.get_object('window') new_object.finish_initializing(builder) return new_object def finish_initializing(self, builder): """Treat this as the __init__() method. Arguments pass in must be passed from __new__().""" builder.connect_signals(self) # Add any other initialization here
Notice that our MainWindow class inherits from gtk.Window. The __gtype_name__ variable creates a type name that is the same as our class. The __new__() method is passed the class inherited. The try/except block creates a Builder object and loads the Glade file. We create new_object and assign it to Builder’s window object. You will want to replace window with the name of your window object used when creating the window in Glade. We then call the new_object’s finish_initializing method, pass it the Builder object we created. You can treat this method as a stand in for an __init__() of the class. If you have objects you need to pass to the class, you will first pass them to __new__() and __new__() can pass them on to finish_initializing(). Once finish_initializing() returns, __new__() returns new_object.
The only thing that finish_initializing() has to do is call Builder’s connect_signals(). However, you will probably want to finish up any other initialization you need for the window, like getting objects you need to interact with from Builder, initializing class objects, etc.
The Glade File
In order for all this to work, we need to edit the Glade UI file and make one small change. In order for new_object to call finish_initializing(), the class type it gets from Builder’s get_object() method must be the same as our class name. Open the Glade file for editing and change the window’s class from GtkWindow or GtkDialog to the created class name.
Displaying the Window
The rest is just creating an instance of the class, calling show(), and gtk.main().
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, gtk import MainWindow if __name__ == "__main__": app = MainWindow.MainWindow() app.show() gtk.main()
That’s all there is to it. You now have a GTK Window class that you can create using the new-style Python classes. The advantage to this method is you do not have to reference the class and then the window object, because the class is a GTK Window.