Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
84 views
in Technique[技术] by (71.8m points)

python - Is it possible to have a standard style for a widget?

I want all of the buttons in my gui to have the same style. Right now I manually write in the attributes I want but it takes up so much space. Also, if I wanted to change the style I would have to go to every single button. Is it possible to have a style i define once and then reference it when making all buttons? Something like the following:

basic_style = 
     {'background': 'blue',
     'foreground':'white', 
     'font':'Helvetica 8 bold'} 

self.btn = tk.Button(text = 'Hello', style = basic_style)

I know its possible to do something like this:

self.btn['text'] = 'Bye'

but that still doesn't help me much.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are at least four ways I can think of to do this: using the option database, passing dictionaries of options, using ttk, and creating custom classes.

Using the option database

There are several ways to accomplish what you want. The original support for this is based on the X11 windowing system option database. Every widget has a class, and every class can have it's options set.

You do this through the option_set method of the root window (as well as option_readfile), specifying a pattern, and the default value.

Example:

import tkinter as tk

root = tk.Tk()

root.option_add("*Font", "Helvetica 8 bold")
root.option_add("*Background", "blue")
root.option_add("*Foreground", "white")

button1 = tk.Button(root, text="Hello", command=lambda: print("Hello"))
button2 = tk.Button(root, text="World", command=lambda: print("world"))

button1.pack()
button2.pack()

root.mainloop()

Note: you must do this after creating the root window but before creating any widgets you want to be affected by this.

How to use the option database can be a bit complex, though it does make it possible to compute entire themes if you're willing to take the time to do it. One of the best -- though oldest -- descriptions comes straight from one of the core developers of tcl/tk here: http://www.cs.man.ac.uk/~fellowsd/tcl/option-tutorial.html. This requires a little bit of mental gymnastics to translate the tcl/tk code to python/tkinter, but the python docs describe how to do that (see Mapping basic tk into tkinter

Using dictionaries.

You can indeed pass in a dictionary of options, with a couple of small caveats. This dictionary must be the first argument after the parent, and it must be before any other keyword arguments.

Example:

import tkinter as tk

basic_style = {'background': 'blue', 'foreground': 'white', 'font': 'Helvetica 8 bold'}

root = tk.Tk()
button1 = tk.Button(root, basic_style, text="Hello", command=lambda: print("Hello"))
button2 = tk.Button(root, basic_style, text="World", command=lambda: print("world"))

button1.pack()
button2.pack()

root.mainloop()

I don't if this is documented anywhere, but you can see that it's supported by looking at the actual tkinter code.

Using the ttk widgets

"ttk" stands for "themed tk". The whole idea was to re-implement tk with the ability to apply themes. ttk has most of the same widgets as tkinter, plus a few that it doesn't have (for example, the treeview widget).

Example:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

style = ttk.Style()
style.configure('Custom.TButton',
                background="blue", foreground="white",
                font='Helvetica 8 bold')

button1 = ttk.Button(root, text='Hello', style='Custom.TButton')
button2 = ttk.Button(root, text='Hello', style='Custom.TButton')

button1.pack()
button2.pack()

root.mainloop()

Unfortunately, there's almost no good documentation on how to configure the themes. It's a bit confusing and non-standard, but the results can be quite polished if you're willing to put in the effort.

The best resource for learning how to create themes is in the Styles and Themes section of tkdocs.com

Creating custom classes

Finally, a fourth option is to create custom classes. Your classes can inherit from the built-in classes and force options to be set if not provided.

Example:

import tkinter as tk

class CustomButton(tk.Button):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault("background", "blue")
        kwargs.setdefault("foreground", "white")
        kwargs.setdefault("font", "Helvetica 8 bold")

        super().__init__(*args, **kwargs)

root = tk.Tk()

button1 = CustomButton(root, text="Hello", command=lambda: print("Hello"))
button2 = CustomButton(root, text="World", command=lambda: print("world"))

button1.pack()
button2.pack()

root.mainloop()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...