是否可以将 canvas 作为按钮的图标?
Is it possible to put a canvas as the icon of a button?
我在 Tkinter 中绘制了漂亮的多边形 canvas。我想把它作为 Tkinter 按钮的图标。
我在 this 中看到了如何在 canvas 上放置一个按钮,但这会掩盖多边形。当然,如果我将多边形放在按钮上,则无法访问该按钮。
我尽量避免使用外部图像。我想保持代码独立,而不是依赖于图像的路径。如果我们移动代码,事情就会崩溃。
from Tkinter import *
class Example(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.widget()
def Xshape (self,canvas,x,y,p,t,outline='black',fill='green',width=1):
points = []
s = t - p
for i in (1,-1):
points.extend(( x, y + (i*p) ))
points.extend(( x + (i*s), y + (i*t) ))
points.extend(( x + (i*t), y + (i*s) ))
points.extend(( x + (i*p), y))
points.extend(( x + (i*t), y - (i*s) ))
points.extend(( x + (i*s), y - (i*t) ))
canvas.create_polygon(points,outline=outline,
fill=fill,width=width)
def widget(self):
cWidth=64.
cHeight=64.
self.canv = Canvas(frame,width=cWidth,height=cHeight)
self.Xshape(self.canv, (cWidth+2)/2,(cHeight+2)/2, cHeight/5,cHeight/2)
self.toggle = Button(frame,relief=FLAT,text='test')
self.win = self.canv.create_window(cWidth/2,cHeight/2,anchor=CENTER,window=self.toggle)
self.canv.grid(row=0,column=2)
root = Tk()
root.geometry('100x100+10+50')
root.wm_title("Telescope Health Status")
root.grid_rowconfigure( 1, weight=1)
root.grid_columnconfigure( 0, weight=1)
frame = Frame(root,bg='light blue',padx=30)
frame.grid(row=0, column=0, columnspan=20, sticky='ew')
app = Example(root)
app.mainloop()
这只会在多边形上放置一个按钮。我想把多边形放在按钮里面。
您可以通过在 Enter、Leave 和鼠标事件上使用绑定,使 canvas 本身模拟按钮的行为,而不是将 canvas 放在按钮中:
Canvas浮雕设置为"raised",边框宽度为 1,使其看起来像一个按钮
当光标进入Canvas
时背景颜色变为浅灰色
按下鼠标按钮1时浮雕设置为"sunken"
参数中给出的命令在释放按钮 1 时执行,但前提是光标仍在 Canvas 上并且浮雕返回 "raised"
当光标离开 Canvas
时浮雕设置回 "raised" 并且恢复正常背景颜色
from Tkinter import *
class ButtonCanvas(Canvas):
def __init__(self, master=None, command=lambda: None, **kw):
Canvas.__init__(self, master, relief="raised", bd=1, **kw)
self._bg = self.cget("bg")
cWidth = 64
cHeight = 64
self.configure(width=64, height=64)
self.Xshape((cWidth+2)/2,(cHeight+2)/2, cHeight/5,cHeight/2)
self.command = command
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
self.bind("<ButtonPress-1>", self.on_b1press)
self.bind("<ButtonRelease-1>", self.on_b1release)
def on_enter(self, event):
self.configure(background="#ececec")
def on_leave(self, event):
self.configure(background=self._bg)
self.configure(relief="raised")
def on_b1press(self, event):
self.configure(relief="sunken")
def on_b1release(self, event):
self.configure(relief="raised")
if self.winfo_containing(event.x_root, event.y_root) == self:
self.command()
def Xshape (self,x,y,p,t,outline='black',fill='green',width=1):
points = []
s = t - p
for i in (1,-1):
points.extend(( x, y + (i*p) ))
points.extend(( x + (i*s), y + (i*t) ))
points.extend(( x + (i*t), y + (i*s) ))
points.extend(( x + (i*p), y))
points.extend(( x + (i*t), y - (i*s) ))
points.extend(( x + (i*s), y - (i*t) ))
self.create_polygon(points,outline=outline,
fill=fill,width=width)
root = Tk()
def cmd():
print("ok")
ButtonCanvas(root, command=cmd).pack()
Button(root, command=cmd).pack()
root.mainloop()
我在 Tkinter 中绘制了漂亮的多边形 canvas。我想把它作为 Tkinter 按钮的图标。
我在 this 中看到了如何在 canvas 上放置一个按钮,但这会掩盖多边形。当然,如果我将多边形放在按钮上,则无法访问该按钮。
我尽量避免使用外部图像。我想保持代码独立,而不是依赖于图像的路径。如果我们移动代码,事情就会崩溃。
from Tkinter import *
class Example(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.widget()
def Xshape (self,canvas,x,y,p,t,outline='black',fill='green',width=1):
points = []
s = t - p
for i in (1,-1):
points.extend(( x, y + (i*p) ))
points.extend(( x + (i*s), y + (i*t) ))
points.extend(( x + (i*t), y + (i*s) ))
points.extend(( x + (i*p), y))
points.extend(( x + (i*t), y - (i*s) ))
points.extend(( x + (i*s), y - (i*t) ))
canvas.create_polygon(points,outline=outline,
fill=fill,width=width)
def widget(self):
cWidth=64.
cHeight=64.
self.canv = Canvas(frame,width=cWidth,height=cHeight)
self.Xshape(self.canv, (cWidth+2)/2,(cHeight+2)/2, cHeight/5,cHeight/2)
self.toggle = Button(frame,relief=FLAT,text='test')
self.win = self.canv.create_window(cWidth/2,cHeight/2,anchor=CENTER,window=self.toggle)
self.canv.grid(row=0,column=2)
root = Tk()
root.geometry('100x100+10+50')
root.wm_title("Telescope Health Status")
root.grid_rowconfigure( 1, weight=1)
root.grid_columnconfigure( 0, weight=1)
frame = Frame(root,bg='light blue',padx=30)
frame.grid(row=0, column=0, columnspan=20, sticky='ew')
app = Example(root)
app.mainloop()
这只会在多边形上放置一个按钮。我想把多边形放在按钮里面。
您可以通过在 Enter、Leave 和鼠标事件上使用绑定,使 canvas 本身模拟按钮的行为,而不是将 canvas 放在按钮中:
Canvas浮雕设置为"raised",边框宽度为 1,使其看起来像一个按钮
当光标进入Canvas
时背景颜色变为浅灰色
按下鼠标按钮1时浮雕设置为"sunken"
参数中给出的命令在释放按钮 1 时执行,但前提是光标仍在 Canvas 上并且浮雕返回 "raised"
当光标离开 Canvas
时浮雕设置回 "raised" 并且恢复正常背景颜色from Tkinter import * class ButtonCanvas(Canvas): def __init__(self, master=None, command=lambda: None, **kw): Canvas.__init__(self, master, relief="raised", bd=1, **kw) self._bg = self.cget("bg") cWidth = 64 cHeight = 64 self.configure(width=64, height=64) self.Xshape((cWidth+2)/2,(cHeight+2)/2, cHeight/5,cHeight/2) self.command = command self.bind("<Enter>", self.on_enter) self.bind("<Leave>", self.on_leave) self.bind("<ButtonPress-1>", self.on_b1press) self.bind("<ButtonRelease-1>", self.on_b1release) def on_enter(self, event): self.configure(background="#ececec") def on_leave(self, event): self.configure(background=self._bg) self.configure(relief="raised") def on_b1press(self, event): self.configure(relief="sunken") def on_b1release(self, event): self.configure(relief="raised") if self.winfo_containing(event.x_root, event.y_root) == self: self.command() def Xshape (self,x,y,p,t,outline='black',fill='green',width=1): points = [] s = t - p for i in (1,-1): points.extend(( x, y + (i*p) )) points.extend(( x + (i*s), y + (i*t) )) points.extend(( x + (i*t), y + (i*s) )) points.extend(( x + (i*p), y)) points.extend(( x + (i*t), y - (i*s) )) points.extend(( x + (i*s), y - (i*t) )) self.create_polygon(points,outline=outline, fill=fill,width=width) root = Tk() def cmd(): print("ok") ButtonCanvas(root, command=cmd).pack() Button(root, command=cmd).pack() root.mainloop()