Tkinter 中的交互式和漂亮的按钮 [英] Interactive and nice looking buttons in Tkinter

查看:72
本文介绍了Tkinter 中的交互式和漂亮的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在探索 Tkinter,我有一个关于按钮 GUI 的问题.我正在寻找创建一个干净简单的平面按钮.我通过互联网(主要是其他 StackOverflow 问题)发现,这可以通过创建图像按钮来实现.但是,有什么方法可以通过在用户将鼠标悬停在按钮上时更改图像或在单击时更改图像来使这些按钮更具交互性?

I'm currently exploring Tkinter and I have a question about Button GUI. I'm looking to create a clean and simple flat button. I have discovered through the internet (mainly other StackOverflow questions) that this is achievable through creating an image button. However, is there any way that I can make these buttons more interactive by changing the image when the user is hovering over the button or changing the image on click?

提前感谢所有回答的人!

thanks in advance to anyone who answers!

推荐答案

这个怎么样?使用 bind 会有所帮助.

How about this? Using bind will help.

from tkinter import *
class InterActiveButton:
    def __init__(self,root):
        self.root = root
        self.root.geometry("800x600")

        self.button1=Button(self.root,bg="dark blue",fg="#dad122",cursor="hand2",text="Button 1",font=("arial",18,"bold"),bd=0,activebackground="dark blue",activeforeground="#dad122")
        self.button1.place(x=10,y=10,width=200,height=50)
        self.button1.bind("<Enter>",self.on_hover)
        self.button1.bind("<Leave>",self.on_leave)
        
        self.button3=Button(self.root,bg="dark blue",fg="#dad122",cursor="hand2",text="Button 2",font=("arial",18,"bold"),bd=0,activebackground="dark blue",activeforeground="#dad122")
        self.button3.place(x=230,y=10,width=200,height=50)
        self.button3.bind("<Enter>",self.on_hover)
        self.button3.bind("<Leave>",self.on_leave)
        
        self.button3=Button(self.root,bg="dark blue",fg="#dad122",cursor="hand2",text="Button 3",font=("arial",18,"bold"),bd=0,activebackground="dark blue",activeforeground="#dad122")
        self.button3.place(x=450,y=10,width=200,height=50)
        self.button3.bind("<Enter>",self.on_hover)
        self.button3.bind("<Leave>",self.on_leave)
    def increase_width(self,ev):
        if self.done!=12:
            ev.place_configure(width=200+self.done)
            self.width_b=200+self.done
            print(self.width_b)
            self.done+=1
            self.root.after(5,lambda:self.increase_width(ev))
    def decrease_width(self,ev):
        if self.done!=12:
            ev.place_configure(width=self.width_b-1)
            self.width_b=self.width_b-1
            print("-------------")
            print(self.width_b)
            self.done+=1
            self.root.after(5,lambda:self.decrease_width(ev))
    def on_hover(self,event,*args):
        self.done=0
        event.widget['bg']="#dad122"
        event.widget['fg']="dark blue"
        #event.widget.place_configure(width=210,height=55)
        self.root.after(5,lambda: self.increase_width(event.widget))
    def on_leave(self,event,*args):
        self.done=0
        event.widget['fg']="#dad122"
        event.widget['bg']="dark blue"
        #event.widget.place_configure(width=200,height=50)
        self.root.after(5,lambda: self.decrease_width(event.widget))
        
root=Tk()
ob=InterActiveButton(root)
root.mainloop()


@TheLizzard


Edit by @TheLizzard:

如果您希望能够将其与任何几何管理器一起使用,请使用:

If you want to be able to use it with any geometry manager, use this:

import tkinter as tk


class InterActiveButton(tk.Button):
    """
    This button expands when the user hovers over it and shrinks when
    the cursor leaves the button.

    If you want the button to expand in both directions just use:
        button = InterActiveButton(root, text="Button", width=200, height=50)
        button.pack()
    If you want the button to only expand to the right use:
        button = InterActiveButton(root, text="Button", width=200, height=50)
        button.pack(anchor="w")

    This button should work with all geometry managers.
    """
    def __init__(self, master, max_expansion:int=12, bg="dark blue",
                 fg="#dad122", **kwargs):
        # Save some variables for later:
        self.max_expansion = max_expansion
        self.bg = bg
        self.fg = fg

        # To use the button's width in pixels:
        # From here: https://stackoverflow.com/a/46286221/11106801
        self.pixel = tk.PhotoImage(width=1, height=1)

        # The default button arguments:
        button_args = dict(cursor="hand2", bd=0, font=("arial", 18, "bold"),
                           height=50, compound="c", activebackground=bg,
                           image=self.pixel, activeforeground=fg)
        button_args.update(kwargs)
        super().__init__(master, bg=bg, fg=fg, **button_args)

        # Bind to the cursor entering and exiting the button:
        super().bind("<Enter>", self.on_hover)
        super().bind("<Leave>", self.on_leave)

        # Save some variables for later:
        self.base_width = button_args.pop("width", 200)
        self.width = self.base_width
        # `self.mode` can be "increasing"/"decreasing"/None only
        # It stops a bug where if the user wuickly hovers over the button
        # the button doesn't go back to normal
        self.mode = None

    def increase_width(self) -> None:
        if self.width <= self.base_width + self.max_expansion:
            if self.mode == "increasing":
                self.width += 1
                super().config(width=self.width)
                super().after(5, self.increase_width)

    def decrease_width(self) -> None:
        if self.width > self.base_width:
            if self.mode == "decreasing":
                self.width -= 1
                super().config(width=self.width)
                super().after(5, self.decrease_width)

    def on_hover(self, event:tk.Event=None) -> None:
        # Improvement: use integers instead of "increasing" and "decreasing"
        self.mode = "increasing"
        # Swap the `bg` and the `fg` of the button
        super().config(bg=self.fg, fg=self.bg)
        super().after(5, self.increase_width)

    def on_leave(self, event:tk.Event=None) -> None:
        # Improvement: use integers instead of "increasing" and "decreasing"
        self.mode = "decreasing"
        # Reset the `fg` and `bg` of the button
        super().config(bg=self.bg, fg=self.fg)
        super().after(5, self.decrease_width)


root = tk.Tk()
root.geometry("400x400")

button = InterActiveButton(root, text="Button", width=200, height=50)
# Using `anchor="w"` forces the button to expand to the right.
# If it's removed, the button will expand in both directions
button.pack(padx=20, pady=20, anchor="w")

root.mainloop()

这也解决了用户快速将鼠标悬停在按钮上时按钮无法恢复正常的问题.

This also fixes the problem with the button not returning to normal if the user quickly hovers over the button.

这篇关于Tkinter 中的交互式和漂亮的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆