简体   繁体   English

有关使用ttk.Style()的问题?

[英]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: 为了使ttk.Style()类的实例可用,这个tkinter 指南中说明了语法是:

import ttk
s=ttk.Style()

When typing these command in IDLE, I noticed that ttk.Style() actually has a predefined argument, ie 在IDLE中输入这些命令时,我注意到ttk.Style()实际上有一个预定义的参数,即

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() ? 问题1:我什么时候需要在ttk.Style()声明master争论? Eg 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). 例如,在上面的脚本中,如果我在class myWidget编写self.s = ttk.Style()self.s = ttk.Style(master=self.parent) ,我会得到相同的结果(参见图1)。

Question 2: Is there a need to prefix s=ttk.Style() with self ? 问题2:是否有必要前缀s=ttk.Style()self I get the same result as shown in Fig1 with and without the self prefix. 我得到的结果如图1所示,有和没有self前缀。

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? 问题3:如果我重新命名'my.TFrame'类myWidget,因为'App.TFrame' (这个名字是在使用class App )时,背景色class App变为紫色太(颜色相同class myWidget为什么。考虑到不同类中的变量名是唯一的,这是否发生了?

Question 4: The names 'App.TFrame' and 'my.TFrame' were called before it was declared. 问题4:名称'App.TFrame''my.TFrame'在声明之前被调用。 Why did python or tkinter not complain or give an error but allowed the script to execute? 为什么python或tkinter没有抱怨或给出错误但允许脚本执行?

图。1

Figure 1 图1

Fig2

Figure 2 图2

When do I need to declare the master arguement in ttk.Style() ? 我什么时候需要在ttk.Style()声明master争论?

Probably never, except the case when tkinter doesnt support the default root . 可能永远不会,除了tkinter不支持default rootdefault root When you pass None as the master, the master becomes the current root instance of Tk class. 当您将None作为主服务器传递时,主服务器将成为Tk类的当前root实例。

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. 所述的主要目的masterroot或任何tk -widget)是委托的实例tkStyle ,使得Style可以是能够执行Tcl -相关的命令。

No more, no less. 不多也不少。


Is there a need to prefix s=ttk.Style() with self ? 是否有必要前缀s=ttk.Style()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. 在你的代码的上下文中 - self是没有意义的,因为你在__createStyle函数的范围内设置样式。

Otherwise, if you wish to keep the reference, it makes sense to prefix with self. 否则,如果您希望保留引用,则以self.为前缀是有意义的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? 如果我重新命名my.TFrame类myWidget,因为App.TFrame (这个名字是在使用class App )时,背景色class App变为紫色太(颜色相同class myWidget ,为什么发生这种情况因为变量名在不同的班级是独特的?

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. 创建的样式是一个全局的东西,它可以在运行时进行查找,所有相关的小部件都会对这些chages做出反应。


The names App.TFrame and my.TFrame were called before it was declared. 名称App.TFramemy.TFrame在声明之前被调用。 Why did python or tkinter not complain or give an error but allowed the script to execute? 为什么python或tkinter没有抱怨或给出错误但允许脚本执行?

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. 当您传递类似<any_sensible_name>.<any_relevant_and_existing_basestyle>ttk知道您需要基本样式的变体,因此它隐式创建一个继承所有基本属性的变体。

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: 尝试使用更无意义的东西,比如没有点的当前样式名称( ttk.Frame.__init__(..., style='AppTFrame', ...) ),这会给你所需的错误:

_tkinter.TclError: Layout AppTFrame not found

Only a partial Answer, but I suppose @Bryan Oakley will entlighten us sooner or later. 只是部分答案,但我想@Bryan Oakley迟早会帮助我们。

Question 3: 问题3:
If you use "App.TFrame" instead of "my.TFrame" inside your MyWidget Class, you override the predefined style properties. 如果在MyWidget类中使用“App.TFrame”而不是“my.TFrame”,则会覆盖预定义的样式属性。

Short example: 简短的例子:
If you style "TFrame" , all "TFrame" ( == Tkinter.Frame/ttk.Frame ) instances will be affected. 如果您设置"TFrame"样式,则所有"TFrame" (== Tkinter.Frame / ttk.Frame)实例都会受到影响。
This is also sometimes referred to as "root-Style". 这有时也被称为“root-Style”。
If you define another "somename.TFrame" and set it for one Object of type frame, it will be styles according "somename.TFrame" . 如果您定义另一个"somename.TFrame"并将其设置为一个类型为frame的Object,则它将是"somename.TFrame"样式。

Question 4: 问题4:
The lookup names only override default styles. 查找名称仅覆盖默认样式。
As long as they have no properties, they do not override a thing. 只要它们没有属性,它们就不会覆盖任何东西。
This "assignment" results in a tcl call and has no specific error handling inside the Tkinter / ttk Sources (used in BaseWidget class). 这个“赋值”导致tcl调用,并且在Tkinter / ttk Sources(在BaseWidget类中使用)中没有特定的错误处理。

I can only tell that tcl does not throw an error here but I am not a tcl expert myself. 我只能说tcl不会在这里抛出错误,但我自己不是tcl专家。

I hope this at least helps a bit. 我希望这至少有点帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM