GtkInfobars for a GTK+ application I instantiate GtkInfobars a lot in my GTK+ application in order to communicate with the user. There are various types of infobars, depending on the message. Basically, any infobar could be a combination of the 4 different infobar message types and 5 different icons (which are painted on the left side of the infobar).

Initially, I would call my custom infobar function like this:

infobar("Message. Woo.", type=gtk.MESSAGE_INFO, icon=gtk.STOCK_DIALOG_WARNING, timeout=5)


After a while I decided I wanted to simplify all the creation calls... so I modified my infobar function so that I could do this:

infobar("Message. Woo.", type=(1,3), timeout=3)


I feel like the second way is better and that it's worth the code obfuscation, but I suspect not everyone will agree with me.

def infobar(self, msg=None, type=(1,1), timeout=3, vbox=None):
    """Popup a new auto-hiding InfoBar."""

    # List of possible infobar message types
    msgtypes = [0,
                gtk.MESSAGE_INFO,      # 1
                gtk.MESSAGE_QUESTION,  # 2
                gtk.MESSAGE_WARNING,   # 3
                gtk.MESSAGE_ERROR]     # 4

    # List of possible images to show in infobar
    imgtypes = [gtk.STOCK_APPLY,            # 0
                gtk.STOCK_DIALOG_INFO,      # 1
                gtk.STOCK_DIALOG_QUESTION,  # 2
                gtk.STOCK_DIALOG_WARNING,   # 3
                gtk.STOCK_DIALOG_ERROR]     # 4

    ibar                    = gtk.InfoBar()
    ibar.set_message_type   (msgtypes[type[0]])
    if vbox:
        # If specific vbox requested: assume ibar for filemode, add cancel button
        ibar.add_button     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        ibar.connect        ('response', self.cleanup_filemode)
    else:
        # If no specific vbox requested: do normal ibar at the top of message area
        vbox = self.vbox_ibar
        ibar.add_button     (gtk.STOCK_OK, gtk.RESPONSE_OK)
        ibar.connect        ('response', lambda *args: ibar.destroy())
    vbox.pack_end           (ibar, False, False)
    content                 = ibar.get_content_area()
    img                     = gtk.Image()
    img.set_from_stock      (imgtypes[type[1]], gtk.ICON_SIZE_LARGE_TOOLBAR)
    content.pack_start      (img, False, False)
    img.show                ()
    if msg:
        # If msg was specified, show it, but change the default color
        label               = gtk.Label()
        label.set_markup    ("&lt;span foreground='#2E2E2E'&gt;{}&lt;/span&gt;".format(msg))
        content.pack_start  (label, False, False)
        label.show          ()
    # FIXME: Why doesn't Esc trigger this close signal?
    ibar.connect            ('close', lambda *args: ibar.destroy())
    ibar.show()
    if timeout:
        glib.timeout_add_seconds(timeout, ibar.destroy)
    return ibar
I'd move all of those message into an external resource file something like:

&lt;message id="file.open.fail" type="warning" icon="error" delay="5"&gt;
    &lt;b&gt;Error. Could not open file:&lt;i&gt;&lt;tt&gt;&lt;small&gt;{filename}&lt;/small&gt;&lt;/tt&gt;&lt;/i&gt;&lt;/b&gt;
&lt;/message&gt;


Then I'd simply pop the message using:

self.infobar('file.open.fail', filename = filename)


That should cleanup the calls to infobar, and make it easier to do things like provide strings for a different language. 

EDIT:

Quick hack of an implementation

from xml.etree.ElementTree import XML, tostring

# of course, you'd want to load this from an external file
message_file = XML("""
&lt;messages&gt;
    &lt;message id="file.open.fail" type="warning" icon="error" delay="5"&gt;
        &lt;b&gt;Error. Could not open file:&lt;i&gt;&lt;tt&gt;&lt;small&gt;{filename}&lt;/small&gt;&lt;/tt&gt;&lt;/i&gt;&lt;/b&gt;
    &lt;/message&gt;
    &lt;message id="file.open.good" type="warning" icon="error" delay="5"&gt;
        &lt;b&gt;File opened!&lt;/b&gt;
    &lt;/message&gt;
&lt;/messages&gt;
""")

messages = {}
for message in message_file.findall("message"):
    messages[message.attrib['id']] = message

def message(id, **kwargs):
    message_detail = messages[id]
    text = ''.join( tostring(node) for node in message_detail)
    return text.strip().format(**kwargs)

print message('file.open.fail', filename = 'file.txt')
print message('file.open.good', filename = 'file.txt')


Doesn't try to handle type/icon/delay. You'll probably also want to consider how you want to do whitespace.