I have coded multiple buttons in my Tkinter program, and I want to change the text colour of all of them to blue. I know I could type 'fg="blue"'every time I create a new button, but I'm looking for a way to select all the buttons in my program, and change the background colour of all of them at the same time.
So far I've tried
for AllButtons in (Button1, Button, ect.)
But it still takes a long time and I'll have to add to the list every time I make a new button. What's the most efficient way of changing the text colour of all the buttons in my program?
You can use ttk widgets and their style to change the appearance of all of the widgets of a specific class at once.
Consider the following example, clicking on the change style button will change the text color from red to blue.
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x110')
self.resizable(0, 0)
self.style = ttk.Style(self)
self.style.configure('W.TButton', foreground = 'red')
# login button
login_button = ttk.Button(self, text="Login",style="W.TButton")
login_button.grid(column=1, row=1, sticky=tk.E)
change_button = ttk.Button(self, text="Change Style",style="W.TButton", command=self.changeStyle)
change_button.grid(column=1,row=2,sticky=tk.E)
def changeStyle(self):
print("Change")
self.style.configure('W.TButton', foreground='blue')
if __name__ == "__main__":
app = App()
app.mainloop()
All of the buttons are mapped to a "W.TButton" style so when we change that style, all of the widgets associated with that style will change their appearance.
Related
i have created window, in that window i put frame. Then i want to create two labels after them button widget.
But, button widget appears upper than second label widget even though i put btn in row=2, and label2 in row=1. It 's hard for me to get why?
from tkinter import *
window=Tk()
window.geometry('620x540+33+33')
var_pg=StringVar()
var_pg.set('Page 001 placeholder')
class lbl_custom(Label):
def __init__(self,frame_window):
super().__init__()
self['width']=33
self['font']='Segoe 12'
frame_submit=Frame(window)
lbl_page_num01=Label(frame_submit,width=33,textvariable=var_pg,font='Segoe 12')
lbl_page_num02=lbl_custom(frame_submit)
lbl_page_num02['text']='Page 002 placeholder'
btn_submit=Button(frame_submit,width=33,relief=RAISED,text='submit')
frame_submit.grid(row=0,column=0)
lbl_page_num01.grid(row=0,column=0)
lbl_page_num02.grid(row=1,column=0)
btn_submit.grid(row=2,column=0)
window.mainloop()
Now, it is for sure that. Every label widget which is created by class inheritance is going down than button nonetheless grid placeholder. But if I create it as Label() class it will be upper than button. Why it is so?
You must pass the parent object when calling super, otherwise your custom object will always be a child of the root window.
class lbl_custom(Label):
def __init__(self,frame_window):
super().__init__(frame_window)
# ^^^^^^^^^^^^
You can pass other options as well, which will save you a couple lines of code:
class lbl_custom(Label):
def __init__(self,frame_window):
super().__init__(frame_window, width=33, font=("Segoe 12",))
I have a small app on Linux in which I sub-class the Frame class from tkinter and sometime the widgets are only drawn after I press the alt button. Everything works fine, though this is the first time I use this GUI and I may miss something.
Follows a short example of my code:
from tkinter import *
class MyFrame(Frame):
def one_method(self):
root_frame.geometry("200x400")
button = Button(self, command=self.clean_and_draw_more_widget, text="Hello")
button.pack(side=TOP) #I also use grid()
the main driver code:
root_frame = Tk()
root_frame.title("Window")
frame = MyFrame(root_frame)
frame.pack()
root_frame.mainloop()
As you can see nothing compless, but still I have this problem.
EDIT
I use grid() and pack() but each one in different methods
Thanks for helping
I'm designing a GUI application using Tkinter and for this project, I need buttons for the menu. While looking into the buttons I wasn't blown away by the customization options that come with the buttons, especially when I found out that you can bind click arguments to rectangles.
This allows me to customize the "button" in (almost) limitless ways, but to allow me to put text on the button I need to create a rectangle element and a text element and bind them together using Tkinter's tag_bind property.
One of the design properties of the button that I wanted was active fill when the user moused over the element. Right now I'm just using activefill="" which works, except the text element and the button element will only fill while the mouse is over that element. So, for example, when I mouse over the button the button excluding the text will highlight and vise versa when I mouse over the text.
Below is a simplified (for brevity) version of what I use to generate the buttons;
button = canvas.create_rectangle(button_width, button_height, 10, 10, fill="000", activefill="111", tags="test")
text = canvas.create_text((button_width/2), (button_height/2), activefill="111", tags="test")
canvas.tag_bind("test", "<Button-1>", "foo")
Is there a way to bind the active fill function to a tag rather than a specific element?
Another option is that I completely missed a bunch of information about customizing the buttons in Tkinter, and I would not be apposed to learning about that.
Option 1
I would personally not go for the presented solution. I do not know if you are using the button provided by tk or ttk. But, with the tkinter.tk, you could absolutely change the appearance of the button.
Following, I give you an example that produces a button with the following characteristics:
Blue foreground
Flat appearance
When hovered, the background is green
When pressed, the background is red
The code is as follows:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
btn['background'] = 'green'
def on_leave(e):
btn['background'] = 'white'
# Create the button
btn = tk.Button(root, background='white', activebackground='red', foreground='blue',relief='flat',text='Test',width=20)
btn.pack()
# Bindings
btn.bind("<Enter>", on_enter)
btn.bind("<Leave>", on_leave)
# Loop
root.mainloop()
Option 2
If even after having tried the tk.Button, you are not glad with the result, I would create a Frame containing a Label (you can do nearly anything with that combination). Then, you could change the background of the frame according to any user action, like:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
lab['background'] = 'green'
def on_leave(e):
lab['background'] = 'white'
# Click
def on_click(e):
print("hi")
# Create the frame with a label inside
fr = tk.Frame(root)
lab = tk.Label(fr, text="Test", width=20, background="white")
# Packing
fr.pack()
lab.pack()
# Bindings
fr.bind("<Enter>", on_enter)
fr.bind("<Leave>", on_leave)
lab.bind("<Button-1>", on_click)
# Loop
root.mainloop()
You could even create a class with the above combination.
Can tkinter create custom buttons from an image or icon like this?
It's possible!
If you check out the button documentation, you can use an image to display on the button.
For example:
from tkinter import *
root = Tk()
button = Button(root, text="Click me!")
img = PhotoImage(file="C:/path to image/example.gif") # make sure to add "/" not "\"
button.config(image=img)
button.pack() # Displaying the button
root.mainloop()
This is a simplified example for adding an image to a button widget, you can make many more cool things with the button widget.
I created a library called CustomTkinter, and with it you can create more or less exactly what is shown in the images above. CustomTkinter provides new widgets for Tkinter, which can be customised in color and shape. Here I tried to create something similar to the image above:
You can find the example code to the above image here.
There is not also a Button, but many other elements, and it also supports a dark and light theme:
You can check out the library here:
https://github.com/TomSchimansky/CustomTkinter
A simple example would be:
import tkinter
import customtkinter
customtkinter.set_appearance_mode("System")
customtkinter.set_default_color_theme("blue")
root_tk = customtkinter.CTk() # create CTk window like the Tk window
root_tk.geometry("400x240")
def button_function():
print("button pressed")
# Use CTkButton instead of tkinter Button
button = customtkinter.CTkButton(master=root_tk, command=button_function)
button.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
root_tk.mainloop()
which gives the following on macOS:
I have created a python GUI application. It works great, and I've styled everything to my liking, save for the ComboBox. Styling on the ttk.Combobox doesn't seem to work.
That should give an idea of the material style I'm going for. Here's the styling block I have for the combobox.
globalStyle = ttk.Style()
globalStyle.configure('TCombobox', foreground=textColor, background=backgroundColor, fieldbackground=selectColor, fieldforeground=textColor, font='Verdana')
The only thing I have been able to successfully change is the text and the foreground color. I am looking to edit the following attributes:
Text color
Field background
Dropdown text color
Dropdown background
EDIT: I should mention that the color variables used are all valid hex color codes.
selectColor = '#333333'
backgroundColor = '#444444'
foregroundColor = '#555555'
textColor = '#999999'
So I ran in to the same issue but found most of the solution here. All you have to do is add the following to your code:
option add *TCombobox*Listbox.background color
option add *TCombobox*Listbox.font font
option add *TCombobox*Listbox.foreground color
option add *TCombobox*Listbox.selectBackground color
option add *TCombobox*Listbox.selectForeground color
Then to change the font inside the box (when the drop down isn't present) add font='font_style' to your code.
So in my case I had:
class CreateProfile(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg='dodgerblue4')
label = tk.Label(self, text="Create Profile", font=large_font, bg='dodgerblue4', fg='deepskyblue')
label.grid(columnspan=10, row=0, column=0, pady=5, padx=5)
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(1, weight=1)
self.option_add("*TCombobox*Listbox*Background", "dodgerblue")
self.option_add("*TCombobox*Listbox*Font", "pirulen")
self.list_c = ttk.Combobox(self, values=("1", "2", "3", "4"), font='pirulen')
self.list_c.grid(row=1, column=1, pady=5, padx=5)
Make sure you also have the following imports:
import tkinter as tk
import tkinter.ttk as ttk
My issue is I'm only able to change the background color of the actual box (when the drop down isn't present). I'm still trying to figure out how to change the font color (foreground doesn't work for me), and the color of the box itself. So if anybody could add to this answer that would be great!
I know that this question is half a year old, but I had a similar issue and managed to solve it. For changing the color of a ttk Combobox popdown frame you can use the following code:
# these imports are indeed only valid for python 3.x
import tkinter as tk
import tkinter.ttk as ttk
# for python 2.x the following import statements should work:
# import Tkinter as tk
# import ttk
root = tk.Tk()
# adding the options to the root elements
# (all comboboxes will receive this options)
root.option_add("*background", "#444444"),
root.option_add("*foreground", "#999999"),
# create a combobox
ttk.Combobox(root, values=["Banana", "Coconut", "Strawberry"]).pack()
root.mainloop()
I'm not sure whether I understand the styling mechanisms of tk correctly.
At least the above code works for me on Python 3.2 and Python 3.4