【问题标题】:How to make a Button using the tkinter Canvas widget?如何使用 tkinter Canvas 小部件制作按钮?
【发布时间】:2013-10-22 13:25:02
【问题描述】:

我想从 Canvas 中获取一个按钮。我试过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 行,我可以看到我的画,但我不能(显然)点击它。但是这样一来,按钮小部件覆盖了我的圆圈并显示了一个悲伤的空按钮。

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

【问题讨论】:

    标签: python button tkinter tkinter-canvas


    【解决方案1】:

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

    要完成这种错觉,您需要在 &lt;Enter&gt;&lt;Leave&gt; 上设置绑定(以模拟活动状态),并确保在按钮释放时光标位于按钮上方——注意如何如果您在释放鼠标之前将鼠标移开,则真正的按钮不会做任何事情。

    【讨论】:

    【解决方案2】:

    你可以做的就是将画布绑定到鼠标:

    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 将被调用(本质上,画布现在已成为一个按钮)。

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

    【讨论】:

      猜你喜欢
      • 2022-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多