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):