9

Say I've created a gtk Widget like this:

class AwesomeTextView (gtk.TextView):

    def set_font(self, font_description):
        self.modify_font(pango.FontDescription(font_description))

How can I add my new widget to the palette in the Glade Interface Builder?

enter image description here

David Planella
  • 15,420
  • 11
  • 77
  • 141
Stefano Palazzo
  • 85,787
  • 45
  • 210
  • 227

3 Answers3

8

Okay, this is going to be step by step:

  • Our widget is going to be named AwesomeTextView, the module it's in will be called awesome_text_view. These are the only names we need.

A glade widget consists of two parts, the module and the catalog.

  1. We create a catalog, awesome_text_view.xml, and (as root) save it at /usr/share/glade3/catalogs/

    This is what it looks like:

    <glade-catalog name="awesome_text_view"
        library="gladepython"
        domain="glade-3"
        depends="gtk+">
    
     <init-function>glade_python_init</init-function>
    
     <glade-widget-classes>
       <glade-widget-class title="Awesome TextView"
        name="AwesomeTextView"
        generic-name="awesome_text_view"/>
     </glade-widget-classes>
    
     <glade-widget-group name="python" title="Python">
       <glade-widget-class-ref name="AwesomeTextView"/>
     </glade-widget-group>
    </glade-catalog>
    

    You should copy and adapt this template, as it works. :-)

  2. We create a module, awesome_text_view.py, and (again as root) save it at /usr/lib/glade3/modules/

    Here's what that looks like:

    import gobject
    import gtk
    import pango
    
    
    class AwesomeTextView (gtk.TextView):
    
        __gtype_name__ = 'AwesomeTextView'
    
        def __init__(self):
            gtk.TextView.__init__(self)
    
        def set_font(self, font_description):
            self.modify_font(pango.FontDescription(font_description))
    

    It's now displayed in Glade, and you can add it to your application.

  3. Finally, you'll just need to

        export PYTHONPATH="$PYTHONPATH:/usr/lib/glade3/modules/"
    

That's it!

Here's a little test app showing how to use your widget:

import gtk
import awesome_text_view

class App (object):

    builder = gtk.Builder()

    def __init__(self):
        self.builder.add_from_file("test.glade")
        self.builder.connect_signals(self)
        self.builder.get_object("awesome_text_view1").set_font("mono")
        gtk.main()

    def on_window1_destroy(self, widget):
        gtk.main_quit()


App()
Stefano Palazzo
  • 85,787
  • 45
  • 210
  • 227
  • 2
    So in practice, there is no way to easily distribute the custom widget with your code and let contributors add it to Glade without them having to manually install it on their systems, I understand. Glade is great, a pity that custom widgets cannot be added without having to go into the guts of the system. In any case, nice answer! – David Planella May 29 '12 at 17:50
  • This doesn't work for me in 12.04. Glade prints this: (glade:25053): GladeUI-WARNING **: Failed to load external library 'gladepython' – user1477 Jun 11 '12 at 23:59
1

You need to make a catalog for your widgets, see this folder: /usr/share/glade3/catalogs/ and you'll see gnome.xml, have a look for an example.

See also the gnome documentation:

http://developer.gnome.org/gladeui/stable/catalogintro.html

Martin Owens -doctormo-
  • 19,860
  • 4
  • 63
  • 103
  • Doesn't work :-( It seems that the documentation is simply wrong, I'll update my question. Also, did you mean `gtk+.xml`, or am I just missing `gnome.xml` for some reason? – Stefano Palazzo Apr 13 '11 at 14:26
  • You have to make your own xml file, not modify an existing one. – Martin Owens -doctormo- Apr 13 '11 at 15:17
  • I understood that, it's just that I don't have gnome.xml, and I wondered if that might be indicative of a problem. Instructions in the link you've posted are wrong in any case, still working on it :-) – Stefano Palazzo Apr 13 '11 at 16:00
0

The accepted answer (dated 2011) no longer works for GTK3 in 2023. Here is what awesome_text_view.py should look like:

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Pango


class AwesomeTextView (Gtk.TextView):
    __gtype_name__ = 'AwesomeTextView'

    def __init__(self):
        Gtk.TextView.__init__(self)

    def set_font(self, font_description):
        self.modify_font(Pango.FontDescription(font_description))

No change is required to be made to the catalogue. And there is no need to copy files to system paths, which you may not have access to anyway. Instead use the environment variables GLADE_CATALOG_SEARCH_PATH and GLADE_MODULE_SEARCH_PATH before launching glade like so

GLADE_CATALOG_SEARCH_PATH=/path/to/awesome_widget/catalogue GLADE_MODULE_SEARCH_PATH=/path/to/awesome_widget/modules glade

Finally, save awesome_text_view.py in the directory /path/to/awesome_widget/modules/

Olumide
  • 539
  • 1
  • 7
  • 22