透明背景上的 TKinter 按钮
TKinter button over transparent background
我想了解如何将按钮应用于透明背景,同时保持其形状。当我生成下面的代码时,出现了边框周围的灰色背景,而且看起来也失去了形状。
使用的颜色
边栏:#2E3A4B 占 53%
按钮:#2C2F33 在 100%
from tkinter import *
def btn_clicked():
""" Prints to console a message every time the button is clicked """
print("Button Clicked")
root = Tk()
# Configures the frame, and sets up the canvas
root.geometry("1440x1024")
root.configure(bg="#ffffff")
canvas = Canvas(root, bg="#ffffff", height=1024, width=1440, bd=0, highlightthickness=0, relief="ridge")
canvas.place(x=0, y=0)
background_img = PhotoImage(file=f"background.png")
background = canvas.create_image(719.5, 512.5, image=background_img)
img0 = PhotoImage(file=f"img0.png")
alarm_button = Button(image=img0, borderwidth=0, highlightthickness=0, command=btn_clicked, relief="flat")
alarm_button.place(x=9, y=119, width=90, height=90)
root.resizable(False, False)
root.mainloop()
所需图片
外观:
外观应该如何:
好消息!我能够让 answer to a related question 你发现有用。为了使其更易于重用,我将其转换为正式的 class 并添加了几个方法。此外,我让它在单击时关闭并重新打开图像,以便为用户提供一些视觉反馈,例如“真实”tkinter Button
s 所做的。
请注意,它响应鼠标按钮 <ButtonRelease-1>
事件。在大多数情况下,这是比 <Button-1>
事件更好的选择,因为如果用户不小心按下按钮,他们可以将鼠标从小部件图像上移开以避免触发事件。
事实证明,使用 PIL 模块是不必要的。这是代码:
import tkinter as tk # PEP 8 recommends avoiding `import *`.
class CanvasButton:
""" Create leftmost mouse button clickable canvas image object.
The x, y coordinates are relative to the top-left corner of the canvas.
"""
flash_delay = 100 # Milliseconds.
def __init__(self, canvas, x, y, image_path, command, state=tk.NORMAL):
self.canvas = canvas
self.btn_image = tk.PhotoImage(file=image_path)
self.canvas_btn_img_obj = canvas.create_image(x, y, anchor='nw', state=state,
image=self.btn_image)
canvas.tag_bind(self.canvas_btn_img_obj, "<ButtonRelease-1>",
lambda event: (self.flash(), command()))
def flash(self):
self.set_state(tk.HIDDEN)
self.canvas.after(self.flash_delay, self.set_state, tk.NORMAL)
def set_state(self, state):
""" Change canvas button image's state.
Normally, image objects are created in state tk.NORMAL. Use value
tk.DISABLED to make it unresponsive to the mouse, or use tk.HIDDEN to
make it invisible.
"""
self.canvas.itemconfigure(self.canvas_btn_img_obj, state=state)
BGR_IMG_PATH = "sunset_background.png"
BUTTON_IMG_PATH = "alarm_button.png"
def btn_clicked():
""" Prints to console a message every time the button is clicked """
print("Button Clicked")
root = tk.Tk()
background_img = tk.PhotoImage(file=BGR_IMG_PATH)
bgr_width, bgr_height = background_img.width(), background_img.height()
root.geometry(f'{bgr_width}x{bgr_height}')
root.title("TKinter button over transparent background")
root.configure(bg="white")
canvas = tk.Canvas(root, bg="white", height=bgr_height, width=bgr_width, bd=0,
highlightthickness=0, relief="ridge")
canvas.place(x=0, y=0)
background = canvas.create_image(0, 0, anchor='nw', image=background_img)
canvas_btn1 = CanvasButton(canvas, 0, 128, BUTTON_IMG_PATH, btn_clicked)
canvas_btn2 = CanvasButton(canvas, 0, 256, BUTTON_IMG_PATH, btn_clicked)
root.resizable(False, False)
root.mainloop()
结果截图:
特写:
我想了解如何将按钮应用于透明背景,同时保持其形状。当我生成下面的代码时,出现了边框周围的灰色背景,而且看起来也失去了形状。
使用的颜色
边栏:#2E3A4B 占 53%
按钮:#2C2F33 在 100%
from tkinter import *
def btn_clicked():
""" Prints to console a message every time the button is clicked """
print("Button Clicked")
root = Tk()
# Configures the frame, and sets up the canvas
root.geometry("1440x1024")
root.configure(bg="#ffffff")
canvas = Canvas(root, bg="#ffffff", height=1024, width=1440, bd=0, highlightthickness=0, relief="ridge")
canvas.place(x=0, y=0)
background_img = PhotoImage(file=f"background.png")
background = canvas.create_image(719.5, 512.5, image=background_img)
img0 = PhotoImage(file=f"img0.png")
alarm_button = Button(image=img0, borderwidth=0, highlightthickness=0, command=btn_clicked, relief="flat")
alarm_button.place(x=9, y=119, width=90, height=90)
root.resizable(False, False)
root.mainloop()
所需图片
外观:
外观应该如何:
好消息!我能够让 answer to a related question 你发现有用。为了使其更易于重用,我将其转换为正式的 class 并添加了几个方法。此外,我让它在单击时关闭并重新打开图像,以便为用户提供一些视觉反馈,例如“真实”tkinter Button
s 所做的。
请注意,它响应鼠标按钮 <ButtonRelease-1>
事件。在大多数情况下,这是比 <Button-1>
事件更好的选择,因为如果用户不小心按下按钮,他们可以将鼠标从小部件图像上移开以避免触发事件。
事实证明,使用 PIL 模块是不必要的。这是代码:
import tkinter as tk # PEP 8 recommends avoiding `import *`.
class CanvasButton:
""" Create leftmost mouse button clickable canvas image object.
The x, y coordinates are relative to the top-left corner of the canvas.
"""
flash_delay = 100 # Milliseconds.
def __init__(self, canvas, x, y, image_path, command, state=tk.NORMAL):
self.canvas = canvas
self.btn_image = tk.PhotoImage(file=image_path)
self.canvas_btn_img_obj = canvas.create_image(x, y, anchor='nw', state=state,
image=self.btn_image)
canvas.tag_bind(self.canvas_btn_img_obj, "<ButtonRelease-1>",
lambda event: (self.flash(), command()))
def flash(self):
self.set_state(tk.HIDDEN)
self.canvas.after(self.flash_delay, self.set_state, tk.NORMAL)
def set_state(self, state):
""" Change canvas button image's state.
Normally, image objects are created in state tk.NORMAL. Use value
tk.DISABLED to make it unresponsive to the mouse, or use tk.HIDDEN to
make it invisible.
"""
self.canvas.itemconfigure(self.canvas_btn_img_obj, state=state)
BGR_IMG_PATH = "sunset_background.png"
BUTTON_IMG_PATH = "alarm_button.png"
def btn_clicked():
""" Prints to console a message every time the button is clicked """
print("Button Clicked")
root = tk.Tk()
background_img = tk.PhotoImage(file=BGR_IMG_PATH)
bgr_width, bgr_height = background_img.width(), background_img.height()
root.geometry(f'{bgr_width}x{bgr_height}')
root.title("TKinter button over transparent background")
root.configure(bg="white")
canvas = tk.Canvas(root, bg="white", height=bgr_height, width=bgr_width, bd=0,
highlightthickness=0, relief="ridge")
canvas.place(x=0, y=0)
background = canvas.create_image(0, 0, anchor='nw', image=background_img)
canvas_btn1 = CanvasButton(canvas, 0, 128, BUTTON_IMG_PATH, btn_clicked)
canvas_btn2 = CanvasButton(canvas, 0, 256, BUTTON_IMG_PATH, btn_clicked)
root.resizable(False, False)
root.mainloop()
结果截图:
特写: