10天速通Tkinter库——Day 4:花样button

Day3的时候我们使用Tkinter的组件button创建了按钮,但是这个按钮局限性很大:

  1. 边框问题:即使设置borderwidth=0, highlightthickness=0, relief="flat"(无边框、无高亮点击、按钮平整),但是当我们点击按钮时还是会出现边框,影响美观。
  2. 背景问题:我们虽然可以任意改变按钮的填充颜色,但是几乎无法直接做到按钮透明。即使设置按钮与背景颜色一致,但是还是会受其他组件的影响。

解决方案:

  1. 使用Label组件制作文字或图片按钮。这可以有效避免按钮边框问题,并且使用图片可以大幅增加按钮外观的美感。但是使用文字时还是有文字背景的局限性。
  2. 使用canvas组件绘制,这个解决办法几乎完美。无论是边框还是背景,甚至是按钮形状,都可以达到让人满意的程度。

1. Label_Button

设计思想:使用两张图片作为按钮背景,一张亮,一张暗(初始化),当鼠标移动至按钮上方时,按钮由暗变亮,离开时又变回暗色。

 

def label_button(root):
    # 加载图片
    dark_image = tk.PhotoImage(file="images\CloseButton.png")  # 替换为你的暗图片路径
    light_image = tk.PhotoImage(file="images\CloseButtonHighlight.png")  # 替换为你的亮图片路径

    def on_enter(event):
        """鼠标进入Label时调用的函数"""
        label.config(image=light_image)

    def on_leave(event):
        """鼠标离开Label时调用的函数"""
        label.config(image=dark_image)

    def on_click(event):
        """Label被点击时调用的函数"""
        messagebox.showinfo("点击了!", "按钮被点击了")

    # 创建Label作为按钮
    label = tk.Label(root, image=dark_image, cursor="hand2",bg='lightBlue')
    label.pack(pady=20)

    # 绑定鼠标事件
    label.bind("<Enter>", on_enter)
    label.bind("<Leave>", on_leave)
    label.bind("<Button-1>", on_click)  # 绑定鼠标左键点击事件

效果:

由于图片是有透明通道的,当图片背景与窗口背景颜色设置为同一颜色,那么效果就相当出色,否则就会:

还有一个小技巧,如果插入的图片是矩形,那么可以设置bd=0使得按钮始终无边框。

但是请注意,一个label不能同时加载图片和文本,如果需要同时的话,需要创建两个label。

 2. Canvas_button

Tkinter 的 Canvas 是一个用于在窗口中绘制图形和图像的组件。它允许用户在窗口中添加矩形、圆形、线条、文本和位图等元素。

设计思路:canvas的功能真的很强大,首先我们可以创建一个画布铺满屏幕,然后随意填充图片作为背景,当我们需要按钮时,我们可以使用基础的button,或上述的label_button,甚至可以自己绘制图形作为按钮。重点在于

绘制图形的这三个参数:

  • width:边框宽度
  • outline:边框颜色
  • fill:填充颜色

以及事件函数定义:

    def on_button_click(event):
        tk.messagebox.showinfo("按钮点击", "按钮被点击了")

    def on_hover(event):
        canvas.itemconfig(label, fill="white")
        canvas.itemconfig(button, fill="black")
        canvas.update_idletasks()

    def on_leave(event):
        canvas.itemconfig(label, fill="black")
        canvas.itemconfig(button, fill="white")
        canvas.update_idletasks()

 下面这段代码中,我们绘制了一个矩形作为按钮,矩形内部创建了一个文本。

def canvas_button(root,width,height):
    def on_button_click(event):
        tk.messagebox.showinfo("按钮点击", "按钮被点击了")

    def on_hover(event):
        canvas.itemconfig(label, fill="white")
        canvas.itemconfig(button, fill="black")
        canvas.update_idletasks()

    def on_leave(event):
        canvas.itemconfig(label, fill="black")
        canvas.itemconfig(button, fill="white")
        canvas.update_idletasks()

    # 创建画布
    canvas = tk.Canvas(root, width=width, height=height, bg="white",bd=0)
    canvas.pack()

    # 加载图片
    img = Image.open("images\Almanac_ZombieBack.jpg")
    img = img.resize((width, height), Image.Resampling.LANCZOS)
    photo = ImageTk.PhotoImage(img) 
    canvas.create_image(width//2, height//2, image=photo)
    canvas.photo = photo

    # 创建透明按钮
    button_width = 100
    button_height = 50
    button_x = 390
    button_y = 500

    # 创建按钮,设置透明背景和文字
    # 按钮可以为任意形状,只要设置width为0,不填充颜色,就可以做到透明
    button = canvas.create_rectangle(button_x, button_y, button_x + button_width, button_y + button_height,
                                     width=1,
                                     outline="red",
                                     fill="white"
                                     )
    label = canvas.create_text(button_x + button_width // 2, 
                               button_y + button_height // 2, 
                               text="点击我", fill="black", font=("Arial", 16))

    # 鼠标悬停和离开事件处理
    canvas.tag_bind(label, "<Enter>", on_hover)
    canvas.tag_bind(button, "<Enter>", on_hover)
    canvas.tag_bind(label, "<Leave>", on_leave)
    canvas.tag_bind(button, "<Leave>", on_leave)

    # 点击按钮事件处理
    canvas.tag_bind(button, "<Button-1>", on_button_click)
    canvas.tag_bind(label, "<Button-1>", on_button_click)

结果1:

  • width=1,
  • outline="red",
  • fill="white"

 这个按钮和普通button非常相似,拥有红色外框,未被点击或鼠标置于上方时,是白色背景黑色字体,当鼠标在上方浮动时变为黑色背景白色字体。

结果2:

  • width=0,
  • # outline="red"
  • # fill="white"
  • 注释掉事件处理函数中对填充颜色的修改

 结果三:

  • width=1,
  • outline="black"
  • # fill="white"
  • 注释掉事件处理函数中对填充颜色的修改

 我们可以看出,在使用canvas制作普通按钮时,我们可以对边框颜色、填充颜色、字体颜色进行单独设置,若需要进一步美化,只需绘制更精美的按钮形状或是使用图片作为按钮背景。举个圆角矩形框的例子:

def draw_rounded_rectangle(canvas, x, y, width, height, radius):
    # 绘制左上角的弧形
    canvas.create_oval(x, y, x + radius, y + radius, width=0, fill='white')
    # 绘制右上角的弧形
    canvas.create_oval(x + width - radius, y, x + width, y + radius, width=0, fill='white')
    # 绘制右下角的弧形
    canvas.create_oval(x + width - radius, y + height - radius, x + width, y + height, width=0, fill='white')
    # 绘制左下角的弧形
    canvas.create_oval(x, y + height - radius, x + radius, y + height, width=0, fill='white')
    # 绘制矩形的主体
    canvas.create_rectangle(x + radius, y + radius, x + width - radius, y + height - radius, width=2, outline='black')

3. 总结

今天使用label和canvas制作更精美的按钮,具有非常高的可创造性,可以大幅提升界面美感。源码:

import tkinter as tk
from PIL import Image, ImageTk
from Day2 import *

def label_button(root):
    # 加载图片
    dark_image = tk.PhotoImage(file="images\CloseButton.png")  # 替换为你的暗图片路径
    light_image = tk.PhotoImage(file="images\CloseButtonHighlight.png")  # 替换为你的亮图片路径

    def on_enter(event):
        """鼠标进入Label时调用的函数"""
        label.config(image=light_image)

    def on_leave(event):
        """鼠标离开Label时调用的函数"""
        label.config(image=dark_image)

    def on_click(event):
        """Label被点击时调用的函数"""
        messagebox.showinfo("点击了!", "按钮被点击了")

    # 创建Label作为按钮
    label = tk.Label(root, image=dark_image, cursor="hand2",bg='Blue')
    label.pack(pady=20)

    # 绑定鼠标事件
    label.bind("<Enter>", on_enter)
    label.bind("<Leave>", on_leave)
    label.bind("<Button-1>", on_click)  # 绑定鼠标左键点击事件

def canvas_button(root,width,height):
    def on_button_click(event):
        tk.messagebox.showinfo("按钮点击", "按钮被点击了")

    def on_hover(event):
        canvas.itemconfig(label, fill="white")
        canvas.itemconfig(button, fill="black")
        canvas.update_idletasks()

    def on_leave(event):
        canvas.itemconfig(label, fill="black")
        canvas.itemconfig(button, fill="white")
        canvas.update_idletasks()

    # 创建画布
    canvas = tk.Canvas(root, width=width, height=height, bg="white",bd=0)
    canvas.pack()

    # 加载图片
    img = Image.open("images\Almanac_ZombieBack.jpg")
    img = img.resize((width, height), Image.Resampling.LANCZOS)
    photo = ImageTk.PhotoImage(img) 
    canvas.create_image(width//2, height//2, image=photo)
    canvas.photo = photo

    # 创建透明按钮
    button_width = 100
    button_height = 50
    button_x = 390
    button_y = 500

    # 创建按钮,设置透明背景和文字
    # 按钮可以为任意形状,只要设置width为0,不填充颜色,就可以做到透明
    button = canvas.create_rectangle(button_x, button_y, button_x + button_width, button_y + button_height,
                                     width=1,
                                     outline="red",
                                     fill="white"
                                     )
    label = canvas.create_text(button_x + button_width // 2, 
                               button_y + button_height // 2, 
                               text="点击我", fill="black", font=("Arial", 16))

    # 鼠标悬停和离开事件处理
    canvas.tag_bind(label, "<Enter>", on_hover)
    canvas.tag_bind(button, "<Enter>", on_hover)
    canvas.tag_bind(label, "<Leave>", on_leave)
    canvas.tag_bind(button, "<Leave>", on_leave)

    # 点击按钮事件处理
    canvas.tag_bind(button, "<Button-1>", on_button_click)
    canvas.tag_bind(label, "<Button-1>", on_button_click)

if __name__=="__main__":
    root = tk.Tk()
    window_width = 880
    window_height = 600
    title_and_icon(root)
    window_size(root,window_width,window_height)
    window_location(root,window_width,window_height)
    root.configure(bg='lightBlue')  # 设置窗口背景颜色为红色

    #label_button(root)
    canvas_button(root,window_width,window_height)
    root.mainloop()

  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值