Switching values of tk.call() and ttk.Style().theme_use()
Question:
I have the following function that supposed to switch the theme of my GUI, but I’m dealing with a small issue. The theme switches the first time CheckButton pressed.
But trying it again getting the following errors:
_tkinter.TclError: Theme forest-light already exists
and:
_tkinter.TclError: Theme forest-dark already exists
code:
import tkinter as tk
from tkinter import ttk
themeTCL = 'forest-light.tcl'
themeFiles = 'forest-light'
window = tk.Tk()
window.title("TRANSMITTER")
window.geometry("1024x600")
window.tk.call('source', themeTCL)
ttk.Style().theme_use(themeFiles)
x_cordinate = int((window.winfo_screenwidth()/2) - (window.winfo_width()/2))
y_cordinate = int((window.winfo_screenheight()/2) - (window.winfo_height()/2))
window.geometry("+{}+{}".format(x_cordinate, y_cordinate))
var = tk.IntVar()
var.set(0)
def themeSwitch():
global themeTCL
global themeFiles
if var.get() == 0:
switch.config(text="Light Mode")
themeTCL = 'forest-light.tcl'
themeFiles = 'forest-light'
window.tk.call('source', themeTCL) # this line
ttk.Style().theme_use(themeFiles) # this line
elif var.get() == 1:
switch.config(text="Dark Mode")
themeTCL = 'forest-dark.tcl'
themeFiles = 'forest-dark'
window.tk.call('source', themeTCL) # this line
ttk.Style().theme_use(themeFiles) # this line
switch = ttk.Checkbutton(window, text="Light Mode", variable=var, command=themeSwitch, style="Switch")
switch.pack(side="top", fill="both", anchor="e", pady=(5, 5), padx=(5, 5))
window.mainloop()
I am no expert at this, but wondering if there is the way to configure the values tk.call() and ttk.Style().theme_use() so I can switch between dark and light mode.
Theme files are from: https://github.com/rdbende/Forest-ttk-theme
Any help would be appreciated. Thanks!
Answers:
try this
see, how self.tk.call(...)
called only once for each theme during initialization and how self.style.theme_use(...)
used to switch between the themes
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("TRANSMITTER")
# self.geometry("1024x600")
self.style = ttk.Style(self)
# import the tcl files
self.tk.call("source", "forest-light.tcl")
self.tk.call("source", "forest-dark.tcl")
# set the theme with the theme_use method
# self.style.theme_use("forest-dark")
# init window frame
frame = ttk.Frame(self)
# set frame to fill x and y axis and expand to fill window
frame.pack(fill='both', expand=True)
# init variable to hold the selected theme
self.selected_theme = tk.StringVar()
self.selected_theme.set("forest-dark")
# create a label frame to hold the radio buttons
theme_frame = ttk.LabelFrame(frame, text='Themes')
# pack the label frame to the window with padding and sticky to the west side
theme_frame.grid(padx=10, pady=10, ipadx=20, ipady=20, sticky='w')
# create a radio button for each theme
for theme_name in self.style.theme_names():
rb = ttk.Radiobutton(
theme_frame,
text=theme_name,
value=theme_name,
variable=self.selected_theme,
command=self.change_theme)
rb.pack(expand=True, fill='both')
def change_theme(self):
self.style.theme_use(self.selected_theme.get())
if __name__ == "__main__":
app = App()
app.mainloop()
I have the following function that supposed to switch the theme of my GUI, but I’m dealing with a small issue. The theme switches the first time CheckButton pressed.
But trying it again getting the following errors:
_tkinter.TclError: Theme forest-light already exists
and:
_tkinter.TclError: Theme forest-dark already exists
code:
import tkinter as tk
from tkinter import ttk
themeTCL = 'forest-light.tcl'
themeFiles = 'forest-light'
window = tk.Tk()
window.title("TRANSMITTER")
window.geometry("1024x600")
window.tk.call('source', themeTCL)
ttk.Style().theme_use(themeFiles)
x_cordinate = int((window.winfo_screenwidth()/2) - (window.winfo_width()/2))
y_cordinate = int((window.winfo_screenheight()/2) - (window.winfo_height()/2))
window.geometry("+{}+{}".format(x_cordinate, y_cordinate))
var = tk.IntVar()
var.set(0)
def themeSwitch():
global themeTCL
global themeFiles
if var.get() == 0:
switch.config(text="Light Mode")
themeTCL = 'forest-light.tcl'
themeFiles = 'forest-light'
window.tk.call('source', themeTCL) # this line
ttk.Style().theme_use(themeFiles) # this line
elif var.get() == 1:
switch.config(text="Dark Mode")
themeTCL = 'forest-dark.tcl'
themeFiles = 'forest-dark'
window.tk.call('source', themeTCL) # this line
ttk.Style().theme_use(themeFiles) # this line
switch = ttk.Checkbutton(window, text="Light Mode", variable=var, command=themeSwitch, style="Switch")
switch.pack(side="top", fill="both", anchor="e", pady=(5, 5), padx=(5, 5))
window.mainloop()
I am no expert at this, but wondering if there is the way to configure the values tk.call() and ttk.Style().theme_use() so I can switch between dark and light mode.
Theme files are from: https://github.com/rdbende/Forest-ttk-theme
Any help would be appreciated. Thanks!
try this
see, how self.tk.call(...)
called only once for each theme during initialization and how self.style.theme_use(...)
used to switch between the themes
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("TRANSMITTER")
# self.geometry("1024x600")
self.style = ttk.Style(self)
# import the tcl files
self.tk.call("source", "forest-light.tcl")
self.tk.call("source", "forest-dark.tcl")
# set the theme with the theme_use method
# self.style.theme_use("forest-dark")
# init window frame
frame = ttk.Frame(self)
# set frame to fill x and y axis and expand to fill window
frame.pack(fill='both', expand=True)
# init variable to hold the selected theme
self.selected_theme = tk.StringVar()
self.selected_theme.set("forest-dark")
# create a label frame to hold the radio buttons
theme_frame = ttk.LabelFrame(frame, text='Themes')
# pack the label frame to the window with padding and sticky to the west side
theme_frame.grid(padx=10, pady=10, ipadx=20, ipady=20, sticky='w')
# create a radio button for each theme
for theme_name in self.style.theme_names():
rb = ttk.Radiobutton(
theme_frame,
text=theme_name,
value=theme_name,
variable=self.selected_theme,
command=self.change_theme)
rb.pack(expand=True, fill='both')
def change_theme(self):
self.style.theme_use(self.selected_theme.get())
if __name__ == "__main__":
app = App()
app.mainloop()