【问题标题】:How to make buttons appear behind a background, or make the buttons background transparent?如何使按钮出现在背景后面,或使按钮背景透明?
【发布时间】:2019-05-01 12:57:00
【问题描述】:

(注意:带边框的按钮是背景的一部分) 我想将真正的按钮放在图像后面,这样我就好像在后台按下按钮,但是,我实际上是在按下它后面的按钮。

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller

    background_image = tk.PhotoImage(file="Mainmenu.png")  # Displays whats in the file
    background_label = tk.Label(self, image=background_image)  # Makes tk.Label display the background_image
    background_label.place(x=0, y=0, relwidth=1, relheight=1)  # Adjusts the height/width

    background_label.image = background_image  # Recognises the label as an image

    button1 = tk.Button(self, text="Play", bg="red", fg="black", height=2, width=15,
                        command=lambda: controller.show_frame("Play"))
    button2 = tk.Button(self, text="Settings", bg="yellow", fg="black", height=2, width=15,
                        command=lambda: controller.show_frame("Settings"))
    button3 = tk.Button(self, text="Quit", bg="white", fg="black", height=2, width=15, cursor="pirate",
                        command=exit)

    button1.place(x="300",y="240")
    button2.place(x="480",y="240")
    button3.place(x="390",y="300")
    button1.config(font=("System", 10))
    button2.config(font=("System", 10))
    button3.config(font=("System", 10))

【问题讨论】:

  • 您无法按照标题中的要求进行操作。但是,您可以将图像添加到按钮本身,然后提供文本以覆盖它。
  • 你为什么要按钮?为什么不让用户直接点击后台呢?
  • Bryan Oakley 如何做到这一点?
  • 您可以将"<Button-1>"绑定到根据鼠标位置执行不同命令的函数。

标签: python tkinter tkinter-canvas


【解决方案1】:

问题:让用户直接点击背景

  1. 定义一个继承自tk.Canvas的类对象

    class Menu(tk.Canvas):
        def __init__(self, parent, image, command, show_areas=False):
            """
            Init a Canvas object, displaying a image
            Bind the Mouse click to a function
            Init a dict to hold the added clickable areas
    
            :param parent: The parent widget
            :param image: The image object
            :param command: The callback command to handle area clicks
            :param show_areas: For debug/trace purpose. If 'True'show the clickable areas.
            """
            super().__init__(parent)
            # Feed TKinter the image
            self._image = image
            self.create_image(0, 0, image=self._image, anchor='nw')
    
            self.callback = command
            self.bind('<Button-1>', self.Button_1_func)
    
            self.show_areas = show_areas
            self.areas = {}
    
  2. 鼠标点击处理函数。
    搜索匹配区域并使用tag 调用.callback 函数

        def Button_1_func(self, event):
            for tag, (x, y, x2, y2) in self.areas.items():
                if event.x in range(x, x2) and event.y in range(y, y2):
                    event.tag = tag
                    self.callback(event)
                    return 'break'
    
  3. 使用给定的tag 和计算的几何图形添加一个新的可点击区域。
    15 * 10 计算区域 width
    5 * 10 计算区域 height
    如果self.show_areasTrue,则使用几何图形创建一个矩形。

        def add_area(self, tag, coord):
            self.areas[tag] = *coord, (coord[0] + (15 * 10)) + 1, (coord[1] + (5 * 10)) + 1
    
            if self.show_areas:
                self.create_rectangle(self.areas[tag])
    

用法

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        # Displays as background_image what's in the file
        self.menu = Menu(self,
                         image=tk.PhotoImage(file="Mainmenu.png"),
                         command=self.command,
                         show_areas=True)
        self.menu.place(x=0, y=0, relwidth=1, relheight=1)

        for tag, coords in [('Play', (300, 240)), 
                            ('Settings', (480, 240)), 
                            ('Quit', (390, 300))]:
            self.menu.add_area(tag, coords)

    def show_frame(self, key):
        # Simulating controller.show_frame
        print('show_frame({})'.format(key))

    def command(self, event):
        if event.tag in ['Play', 'Settings']:
            self.show_frame(event.tag)

        if event.tag == 'Quit':
            self.quit()

if __name__ == "__main__":
    App().mainloop()

用 Python 测试:3.5

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多