Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Questions on using ttk.Style()?

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?

Fig1

Figure 1

Fig2

Figure 2

like image 865
Sun Bear Avatar asked Jan 30 '18 09:01

Sun Bear


1 Answers

When do I need to declare the master arguement in ttk.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() with self?

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 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?

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 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?

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
like image 67
CommonSense Avatar answered Oct 29 '22 13:10

CommonSense