Interactive And Nice Looking Buttons In Tkinter
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 S
Solution 1:
How about this? Using bind
will help.
from tkinter import *
classInterActiveButton:
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)
defincrease_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))
defdecrease_width(self,ev):
if self.done!=12:
ev.place_configure(width=self.width_b-1)
self.width_b=self.width_b-1print("-------------")
print(self.width_b)
self.done+=1
self.root.after(5,lambda:self.decrease_width(ev))
defon_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))
defon_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()
Edit by @TheLizzard:
If you want to be able to use it with any geometry manager, use this:
import tkinter as tk
classInterActiveButton(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 = Nonedefincrease_width(self) -> None:
if self.width <= self.base_width + self.max_expansion:
if self.mode == "increasing":
self.width += 1super().config(width=self.width)
super().after(5, self.increase_width)
defdecrease_width(self) -> None:
if self.width > self.base_width:
if self.mode == "decreasing":
self.width -= 1super().config(width=self.width)
super().after(5, self.decrease_width)
defon_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 buttonsuper().config(bg=self.fg, fg=self.bg)
super().after(5, self.increase_width)
defon_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 buttonsuper().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.
Solution 2:
To make the button change color on hover, you can try the below code. However, I would not suggest using Tkinter if you want your interface to look beautiful. Try Kivy if you can. It really helps in making a natural user interface! Anyways, here's the code for the button to change color on hover:
from tkinter import ttk
import tkinter as tk
# Create a window
root = tk.Tk()
root.geometry("500x500")
# Create style Object
style = ttk.Style()
style.configure("TButton", font=("Calibri", 20, "bold"), borderwidth=4)
# Changes will be reflected# by the movement of mouse.
style.map("TButton", foreground=[("active", "disabled", "green")],
background=[("active", "black")])
# Button 1
btn1 = ttk.Button(root, text="Quit!", command=root.destroy)
btn1.grid(row=0, column=3, padx=100)
# Button 2
btn2 = ttk.Button(root, text="Click me!")
btn2.grid(row=1, column=3, pady=10, padx=100)
# Start tkinter's main loop
root.mainloop()
Post a Comment for "Interactive And Nice Looking Buttons In Tkinter"