2013-10-14 48 views
6

我想从Canvas中获取一个按钮。我试图在按钮小部件中使用pack画布,但那不起作用。谷歌搜索了一下,我发现(这里:How do you create a Button on a tkinter Canvas?)Canvas方法create_window可能会有所帮助。但是我使用它的方式应该有些问题。如何使用tkinter Canvas小部件制作按钮?

import Tkinter 

DIM = 100 

root = Tkinter.Tk() 
frame = Tkinter.Frame(root) 

button = Tkinter.Button(None, width=DIM, height=DIM, command=root.quit) 

circle = Tkinter.Canvas(frame, width=DIM, height=DIM) 
circle.create_oval(5, 5, DIM-5, DIM-5, fill="red") 
circle.create_window(0, 0, window=button) 

frame.grid() 
circle.grid(row=1, column=1) 

root.mainloop() 

如果我抹去create_window线,我可以SE我的画,但我不能(显然)一下就可以了。但通过这种方式,按钮小部件覆盖我的圈子并显示一个令人伤心的空按钮。

基本上,我想创建一个带有红色圆圈的按钮。

回答

10

Tkinter不允许您直接绘制画布以外的小部件,并且画布图形始终位于嵌入小部件的下方。

简单的解决方案是使用画布创建按钮的效果。这样做没有什么特别之处:只需创建一个画布,然后为ButtonPress和ButtonRelease添加绑定以模拟正在按下的按钮。

这里有一个粗略的想法:

class CustomButton(tk.Canvas): 
    def __init__(self, parent, width, height, color, command=None): 
     tk.Canvas.__init__(self, parent, borderwidth=1, 
      relief="raised", highlightthickness=0) 
     self.command = command 

     padding = 4 
     id = self.create_oval((padding,padding, 
      width+padding, height+padding), outline=color, fill=color) 
     (x0,y0,x1,y1) = self.bbox("all") 
     width = (x1-x0) + padding 
     height = (y1-y0) + padding 
     self.configure(width=width, height=height) 
     self.bind("<ButtonPress-1>", self._on_press) 
     self.bind("<ButtonRelease-1>", self._on_release) 

    def _on_press(self, event): 
     self.configure(relief="sunken") 

    def _on_release(self, event): 
     self.configure(relief="raised") 
     if self.command is not None: 
      self.command() 

要完成你要设置<Enter><Leave>绑定(模拟激活状态)的错觉,同时也确保了光标在释放按钮 - 注意如果在释放之前将鼠标移开,实际按钮不会执行任何操作。

1

你可以做的是画布结合小鼠:

import Tkinter 

DIM = 100 

root = Tkinter.Tk() 
frame = Tkinter.Frame(root) 

circle = Tkinter.Canvas(frame) 
circle.create_oval(5, 5, DIM-5, DIM-5, fill="red") 

frame.grid() 
circle.grid(row=1, column=1) 

################################## 
def click(event): 
    root.quit() 

circle.bind("<Button-1>", click) 
################################## 

root.mainloop() 

现在,如果画布内的用户点击,功能click将被调用(实质上,在画布上现在已经做了一个按钮) 。

注意,如果用户在画布中点击任意位置,将会调用该函数click。如果您想使click仅在用户点击该圈子时被调用,则可以使用event.xevent.y来获得点击的坐标xy。一旦你有了这些,你可以运行计算来确定这些坐标是否在圆内。 Here是一个参考。