Reputation: 754
How in TTK can I use the OS default loader theme instead of the tkinter one?
This is an example of a normal progress bar.
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.geometry('400x250+1000+300')
progress_bar = Progressbar(root, orient=HORIZONTAL, length=100, mode='indeterminate')
progress_bar.pack(expand=True)
progress_bar.start()
root.mainloop()
I get a progress bar, but it isn't themed like the OS default progress bar is.
I thought that perhaps a style could make it look like that, so I listed the styles:
Style().theme_names() # ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
I tried each one like so:
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.geometry('400x250+1000+300')
os_default_style = Style()
os_default_style.theme_use('THEME')
os_default_style.configure('osdefault.Horizontal.TProgressbar')
progress_bar = Progressbar(root, orient=HORIZONTAL, length=100, mode='indeterminate', style='osdefault.Horizontal.TProgressbar')
progress_bar.pack(expand=True)
progress_bar.start()
root.mainloop()
They produce ones that are similar, but none are the system. How do I make it look exactly like one used by the system?
Upvotes: 1
Views: 1489
Reputation: 3021
Try this -
from tkinter import *
from tkinter import ttk
root = Tk()
s = ttk.Style()
s.theme_use('winnative')
s.configure("Blue.Horizontal.TProgressbar", foreground='white',
background='blue')
P1 = ttk.Progressbar(root, style="Blue.Horizontal.TProgressbar",
orient="horizontal", length=600, mode="indeterminate",
maximum=4, value=1)
P1.pack()
root.mainloop()
Upvotes: 0
Reputation: 344
I think is a little bit case sensitive the "default OS theme"... xpnative is the close to the native one and almost fool the eyes. I created an test to see the differences (note I use windows 7) and the result for default OS style reveal like xpnative is the winner. vista look same but is a little bigger that is all. Now if OS use simple theme, this two will not work, but other will do... For windows 10, classic tkinter theme is close to this OS theme, but tkinter.ttk will do same thing on windows 10... Is to sensitive this subject. Just on windows are some obstacles, I even do not mentioned Linux... Theme is not so important, if your project is making the job right and is close enough to default theme of the user OS from my view point is more than perfect.
Here is my test:
# Import
import tkinter as tk
import tkinter.ttk as ttk
# Logic
class Main:
def __init__(self, master):
self.master = master
# Create the progress bar
self.progress = ttk.Progressbar(self.master, value=0)
self.progress.pack(expand=False, fill="x", side="top", padx=5, pady=5)
self.progress.start()
# Create two layers for the theme
self.default = self.Layer("Default") # for default foundet ones
self.custom = self.Layer("Custom") # for manual input and debug purpose
# Create the entry and applay elements for the "custom layer"
self.entry = ttk.Entry(self.custom)
ttk.Button(self.custom, text="Apply...", width=15, command=lambda:self.ChangeTheme(self.entry.get().strip())
).pack(side="right")
self.entry.pack(expand=True, fill="x", side="left")
# Get a list of all default themes and create a button for each one
for theme in ttk.Style().theme_names(): self.ThemeDefault(theme)
def ThemeDefault(self, themeName:str) -> None:
ttk.Button(self.default, text=themeName, width=15, command=lambda:self.ChangeTheme(themeName)).pack(side="left")
def Layer(self, text:str) -> tk.Frame:
frame = tk.Frame(self.master)
label = tk.Label(frame, text=text, width=7, anchor="w")
frame.pack(expand=False, fill="x", side="top", padx=5, pady=5)
label.pack(side="left")
return frame
def ChangeTheme(self, themeName:str) -> None:
try: ttk.Style(self.master).theme_use(themeName)
except Exception as e: print(f">> EXCEPTION // {e}")
# Run if this file is the main opened one
if __name__ == "__main__":
root = tk.Tk()
Main(root)
root.mainloop()
This is what is look like the resoult.
Upvotes: 4
Reputation: 1279
Unfortunately, a 'truly native' widget is not possible in Tk. As you can see in the source, a theme simply sets a bunch of settings and it does not do anything you couldn't do yourself. However, finding a good theme will generally do a 'good enough' job (see ASI's answer for more details on this).
If you don't believe me, take a look at the ProgressbarDoLayout
method (and related methods - found here) and you can see that Tk is handling the drawing itself and giving very little to the native software.
Upvotes: 1