Create a custom widget with PyGObject
Question: I am trying to create a custom widget with **PyGObject**. For example I want
to create this `CustomButton` widget which adds an image and a label in a
button (it's just for the example) :

    
    
    #!/usr/bin/python
    #-*- coding: utf-8 -*
    
    from gi.repository import Gtk
    
    class ImageButton(Gtk.Widget):
    
        def __init__(self, label, image):
            Gtk.Widget.__init__(self)
    
            self.hbox = Gtk.HBox()
            self.label = Gtk.Label(label)
            self.image = Gtk.Image.new_from_stock(image, Gtk.IconSize.MENU)
    
            self.hbox.pack_start(self.image, False, False, 3)
            self.hbox.pack_start(self.label, False, False, 3)
    
            self.button = Gtk.Button()
            self.button.add(self.hbox)
    

In another file or class, I can use it like that :

    
    
    button = ImageButton("My label", Gtk.STOCK_HOME)
    

But when I want to use it, I am obliged to call the `button` attribute, like
this :

    
    
    # Connect the "clicked" event 
    button.button.connect("clicked", on_clicked_button)
    
    # Add the button in a container
    window.add(button.button)
    

It works but it is not practical. How to create a custom widget working like
any other widget please :

    
    
    button = ImageButton("My label", Gtk.STOCK_HOME)
    button.connect("clicked", on_clicked_button)
    window.add(button)
    


Answer: I think that your problem it is actually a problem about understanding classes
more then inheritance. If you want your widget to act exactly as a button, it
should be a button.

Take a look to the following example:

    
    
    from gi.repository import Gtk
    
    class ImageButton(Gtk.EventBox):
    
        def __init__(self, label):
    
            Gtk.EventBox.__init__(self)
            self.label = Gtk.Label(label)
            self.add(self.label)    
    
    
    if __name__ == '__main__':
        def on_imagebutton_clicked(button, data=None):
            print("Button has been clicked!")
    
        window = Gtk.Window()
        button = ImageButton("My label")
        button.connect('button-press-event', on_imagebutton_clicked)
        window.add(button)
        window.show_all()
        Gtk.main()
    

Instead of saying that my class it is a `Gtk.Widget`, I said that it is a
`Gtk.EventBox` and I started it like it. From now on `ImageButton` will have
the same attributes and methods like an `Gtk.EventBox`.

*If I've made the same example by using `Gtk.Button` instead of a `Gtk.EventBox` **you could call** `button.connect(..` instead of `buton.connect.connect(..` as you want it in your question. The problem with this is that if `ImageButton` it is a `Gtk.Button` It is not any more possible of modifying it to do things that buttons don't do ( like adding containers and labels).

**In a Few Words:**

You can create a custom widget based in other widget, but only one widget will
be at the top of the tree.

    
    
    --> Parent  
    ---------> Child
    ---------> Child
    

So when you do `self.method` it will always look to:

1) Your parent methods (the one you copied by using
`Gtk.EventBox.__init__(self)`

2) The methods you created.

Alternatively you can lie thanks to this:

    
    
    from gi.repository import Gtk
    
    class ImageButton(Gtk.EventBox):
    
        def __init__(self, label):
    
            Gtk.EventBox.__init__(self)
            self.label = Gtk.Label(label)
            self.add(self.label)    
    
        def set_text(self, text):
            self.label.set_text(text)
    
    if __name__ == '__main__':
        def on_imagebutton_clicked(button, data=None):
            print("Button has been clicked!")
    
        window = Gtk.Window()
        button = ImageButton("My label")
        button.connect('button-press-event', on_imagebutton_clicked)
        button.set_text('New text!!')
        window.add(button)
        window.show_all()
        Gtk.main()
    

Note that I didn't had to call `button.label.set_text(..)` I hope it be clear
enough!

