in my project i was using Tkinter buttons with a background gif as image. Now i have a requirement to add an "icon", given as a base64 string. The Tkinter Button doesn't provide a option to add a icon, or a second image. That's why i have created a custom Button using canvas. Code below:
from Tkconstants import DISABLED
from Tkinter import Tk, Canvas
import Tkinter
import base64
import ImageTk
_FONTCOLOR = "#FFFFFF"
_BGCOLOR = "#787878"
_ICONDATA = '''iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZ
 G9iZSBJbWFnZVJlYWR5ccllPAAAAUJJREFUeNrsVc1qhDAQHq20FnRP7kF68iB9D+99Dp/J5+jdR9Bz8VwU
 PChbQbdo00yYLLuSrW4x9NKBjy+RL5nMZ34MxhjoDBM0h/YExoy3DCYnRtxx3BMbV8QTxxdVvaT7JGYWiV2
 OPbE1GywH9RwDh83xqEiCupHjg6Mmnixa+T5JkrelmuM4fimK4nVJF4bhM6cjLkqWu1vp69P8Q9u2MI7j/P
 OO5hV+yn9wEVEUqRI8yAZOmuc5NE0DWZbBMAznupN95o276KQryxI8z4MgCMD3fajrWqn79Tnoug5c1xVtZ
 LRq04Om8H3bBI7jQN/3oo2M/U0ToO9VVQlrkLH/UwJ2y/HHsG0b97vYRcjYV+mss5N6EWmaqhIc5zZdsWaS
 SUzqHFZW8L5Sd5CLNqgKbXeR9ttU/3vw/yb/eYJvAQYA4v5708p9noAAAAAASUVORK5CYII='''
class DesktopBtn(Tkinter.Button):
    def __init__(self, parent, buttonName, connector=None, **options):
        '''
        @param buttonName: Name of the button
        '''
        Tkinter.Button.__init__(self, parent, **options)
        self._imagePath = 'button.gif'
        self._BtnPresspath = 'buttonP.gif'
        self._BtnPressImage = Tkinter.PhotoImage(file=self._BtnPresspath)
        self._image = Tkinter.PhotoImage(file=self._imagePath)
        self.bind('<ButtonPress-1>', self._on_pressed)
        self.bind('<ButtonRelease-1>', self._on_release)
        self._parent = parent
        self._btnName = buttonName
        self._connector = connector
        self.config(width=70,
                    height=65,
                    borderwidth=0,
                    compound=Tkinter.CENTER,
                    font=("Arial", 9, "bold"),
                    foreground=_FONTCOLOR,
                    activebackground=_BGCOLOR,
                    text=buttonName,
                    wraplength=64,
                    image=self._image,
                    command=self._onClickSwitch,
                    state="disabled")
    def _on_pressed(self, event):
        if self.cget("state") != "disabled":
            self.config(relief="flat")
            self.config(image=self._BtnPressImage)
    def _on_release(self, event):
        if self.cget("state") != "disabled":
            self.config(image=self._image)
    def _onClickSwitch(self):
        self.config(relief="flat")
        if self._connector:
            self._connector.switchDesktop(self._btnName,
                                          "test")
    def getButtonName(self):
        return self._btnName
    def setConnector(self, connector):
        self._connector = connector
class CustomButton(Canvas):
    def __init__(self, parent, buttonname=None, icon=None, command=None):
        Canvas.__init__(self, parent, borderwidth=0, highlightthickness=0)
        self.command = command
        self._imagePath = 'button.gif'
        self._BtnPresspath = 'buttonP.gif'
        self._icon = icon
        self._BtnPressImage = Tkinter.PhotoImage(file=self._BtnPresspath)
        self._image = Tkinter.PhotoImage(file=self._imagePath)
        self.bgimage = self.create_image(35, 35, image=self._image)
        self.text = buttonname
        if self._icon:
            self._icondata = base64.b64decode(self._icon)
            self._iconimage = ImageTk.PhotoImage(data=self._icondata)
            self.create_image(35, 35, image=self._iconimage)
        if self.text and self._icon:
            self.create_text(35, 63, anchor="s",
                             state=DISABLED,
                             text=self.text,
                             font=("arial", 9, "bold"),
                             fill=_FONTCOLOR)
        elif not self._icon:
            self.create_text(35, 45, anchor="s",
                             state=DISABLED,
                             text=self.text,
                             font=("arial", 9, "bold"),
                             fill=_FONTCOLOR)
        self.configure(width=70, height=70, state=DISABLED)
#         if self.cget("state") == "disabled":
#             pass
#         else:
        self.bind("<ButtonPress-1>", self._on_press)
        self.bind("<ButtonRelease-1>", self._on_release)
    def _on_press(self, event):
        self.itemconfig(self.bgimage,image=self._BtnPressImage)
        print "pressed"
    def _on_release(self, event):
        self.itemconfig(self.bgimage,image=self._image)
        if self.command is not None:
            self.command()
tk = Tk()
but = DesktopBtn(tk, "test")
but.pack()
butt_blank = CustomButton(tk)
butt_text = CustomButton(tk, buttonname="test")
butt_icon = CustomButton(tk, icon=_ICONDATA)
butt_icon_text = CustomButton(tk, icon=_ICONDATA, buttonname="test")
butt_blank.pack()
butt_text.pack()
butt_icon.pack()
butt_icon_text.pack()
tk.mainloop()
The first button(class) is the Tkinter Button i used to use. Now i have only problem. How do i disable my canvas custom Button like the the normal Tkinter Button. It should be grayed and ignore mouse events.
According to Tkinter 8.5 reference using the DISABLED state on create_image or even the canvas object, my custom Button should behave like the old Button. I'm using Python 2.7.
Here are the Button images used (button.gif and buttonP.gif):  

 
     
    