To make available an instance of the ttk.Style() class, it was illustrated in this tkinter guide that the syntax is:
import ttk
s=ttk.Style()
When typing these command in IDLE, I noticed that ttk.Style() actually has a predefined argument, i.e.
s=ttk.Style(master=None)
I have written the following test script:
import tkinter as tk
import tkinter.ttk as ttk
class App(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self, parent, style='App.TFrame', relief=tk.SUNKEN,
border=10)
self.parent = parent
self.__createStyle()
self.__createWidgets()
def __createStyle(self):
self.s = ttk.Style()
self.s.configure('.', background='orange', border=100)
self.s.configure('App.TFrame', background='yellow')
self.s.configure('Btn.TButton', background='light blue', border=10)
def __createWidgets(self):
self._label = ttk.Label(self.parent, text='Label packed in root.')
self._label.pack()
self._btn = ttk.Button(self, style='Btn.TButton', command=self.__click,
text='Button packed inside self or class App, which is a ttk.Frame')
self._btn.pack()
def __click(self):
return print('Left Button Clicked!')
class myWidget(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self, parent, style='my.TFrame', relief=tk.GROOVE,
border=10)
self.parent = parent
self.__createStyle()
self.__createWidgets()
def __createStyle(self):
self.s = ttk.Style()
self.s.configure('my.TFrame', background='purple')
self.s.configure('my.TLabel', background='pink', border=10)
self.s.configure('my.TEntry', foreground='red', border=10)
def __createWidgets(self):
self._label = ttk.Label(self, style='my.TLabel',
text='myWidget Label packed in self or class myWidget, which is a ttk.Frame.')
self._label.pack()
self._entry = ttk.Entry(self, style='my.TEntry')
self._entry.pack()
if __name__ == "__main__":
root = tk.Tk()
root.title('Test Style')
root.geometry('500x150')
a = App(root)
a.pack(fill='both', expand=1)
b = myWidget(a)
b.pack()
root.mainloop()
Question 1: When do I need to declare the master
arguement in ttk.Style()
? E.g. in the above script, if I write self.s = ttk.Style()
and self.s = ttk.Style(master=self.parent)
in class myWidget
, I get the same result (see Fig1).
Question 2: Is there a need to prefix s=ttk.Style()
with self
? I get the same result as shown in Fig1 with and without the self
prefix.
Question 3: If I rename 'my.TFrame'
in class myWidget as 'App.TFrame'
(this name was used in class App
), the background colour of the class App
changed to purple color too (same color as class myWidget
. Why did this happened given that variable name in different classes are unique?
Question 4: The names 'App.TFrame'
and 'my.TFrame'
were called before it was declared. Why did python or tkinter not complain or give an error but allowed the script to execute?
Figure 1
Figure 2
When do I need to declare the
master
arguement inttk.Style()
?
Probably never, except the case when tkinter
doesnt support the default root
. When you pass None
as the master, the master becomes the current root
instance of Tk
class.
The main purpose of the master
(root
or any tk
-widget) is to delegate instance of tk
to the Style
, so that the Style
could be able to execute Tcl
-related commands.
No more, no less.
Is there a need to prefix
s=ttk.Style()
withself
?
It depends on your requirements. In context of your code - self
is meaningless, because you're setting up styles in a scope of the __createStyle
function.
Otherwise, if you wish to keep the reference, it makes sense to prefix with self.
If I rename
my.TFrame
in class myWidget asApp.TFrame
(this name was used inclass App
), the background colour of theclass App
changed to purple color too (same color asclass myWidget
. Why did this happened given that variable name in different classes are unique?
Because both of classes share the same frame style, hence the same color. Created style is a global thing, it can be chaged at runtime, and all the relevant widgets will react to these chages.
The names
App.TFrame
andmy.TFrame
were called before it was declared. Why did python or tkinter not complain or give an error but allowed the script to execute?
Why you think they should? When you pass something like <any_sensible_name>.<any_relevant_and_existing_basestyle>
, ttk
knows that you want a variation of a base style, so it's implicitly creates one, which inherits all base properties.
Try that trick with something more meaningless, like your current style name without dot (ttk.Frame.__init__(..., style='AppTFrame', ...)
), which gives you the desired error:
_tkinter.TclError: Layout AppTFrame not found
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With