如何使用tkinter Canvas小部件制作按钮?

2024-04-27 02:53:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从画布上取一个按钮。我试过在按钮小部件中pack画布,但没有成功。搜索一下,我发现(这里:How do you create a Button on a tkinter Canvas?)Canvas方法create_window可能有帮助。但我使用它的方式应该有问题。

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行,我可以查看我的画,但我不能(显然)单击它。但是这样,button小部件覆盖了我的圆圈并显示了一个悲伤的空按钮。

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


Tags: 部件tkinter画布createbuttonrootwindowwidth
2条回答

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>上设置绑定(以模拟活动状态),还要确保光标位于按钮释放上的按钮上—请注意,如果在释放之前将鼠标移开,真正的按钮将不会执行任何操作。

您可以将画布绑定到鼠标:

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是对它的引用。

相关问题 更多 >