2013-10-14 75 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是一個參考。