Возможно ли иметь стандартный стиль для виджета? - PullRequest
0 голосов
/ 06 сентября 2018

Я хочу, чтобы все кнопки в моем графическом интерфейсе имели одинаковый стиль. Прямо сейчас я вручную пишу нужные атрибуты, но это занимает так много места. Кроме того, если бы я хотел изменить стиль, мне нужно было бы перейти к каждой кнопке. Можно ли иметь стиль, который я определяю один раз, а затем ссылаться на него при создании всех кнопок? Примерно так:

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

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

Я знаю, что можно сделать что-то вроде этого:

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

но это все равно мне мало помогает.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Есть как минимум четыре способа сделать это: использовать базу данных опций, передать словари опций, использовать ttk и создать собственные классы.

Использование базы данных опций

Есть несколько способов выполнить то, что вы хотите. Первоначальная поддержка этого основана на базе данных опций оконной системы X11. У каждого виджета есть класс, и у каждого класса могут быть установлены его параметры.

Это можно сделать с помощью метода option_set корневого окна (а также option_readfile), указав шаблон и значение по умолчанию.

Пример:

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()

Примечание: вы должны сделать это после создания корневого окна, но до создания любых виджетов, на которые вы хотите повлиять.

Как использовать базу данных опций, может быть немного сложно, хотя она позволяет вычислять целые темы, если вы не торопитесь. Одно из лучших - хотя и самых старых - описаний пришло прямо от одного из основных разработчиков tcl / tk: http://www.cs.man.ac.uk/~fellowsd/tcl/option-tutorial.html. Для перевода кода tcl / tk в python / tkinter требуется немного умственной гимнастики. , но в документации по Python описывается, как это сделать (см. Отображение базового tk в tkinter

Использование словарей.

Вы действительно можете передать словарь опций с несколькими небольшими оговорками. Этот словарь должен быть первым аргументом после родителя, и он должен быть перед любыми другими аргументами ключевого слова.

* +1025 * Пример:
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()

Не знаю, документировано ли это где-либо, но вы можете увидеть, что это поддерживается, посмотрев на действительный код tkinter.

Использование виджетов ttk

"ttk" означает "тематический tk". Вся идея заключалась в том, чтобы заново реализовать тк с возможностью применения тем. У ttk есть большинство тех же виджетов, что и у tkinter, плюс несколько, которых у него нет (например, виджет TreeView).

* +1034 * Пример: * * одна тысяча тридцать пять
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()

К сожалению, хорошей документации по настройке тем почти нет. Это немного запутанно и нестандартно, но результаты могут быть весьма отточенными, если вы готовы приложить усилия.

Лучший ресурс для изучения того, как создавать темы, находится в разделе Стили и темы на tkdocs.com

Создание пользовательских классов

Наконец, четвертый вариант - создание пользовательских классов. Ваши классы могут наследоваться от встроенных классов и принудительно устанавливать опции, если они не предоставлены.

* +1047 * Пример: * +1048 *
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()
0 голосов
/ 06 сентября 2018

Да, это даже проще, чем вы себе представляете. Просто используйте словарь для распаковки:

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

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

Другим популярным вариантом является создание подкласса с нужным вам стилем и, возможно, другими функциями, такими как всплывающие подсказки или стиль, зависящими от значений или чего-либо еще.

class Justine(tk.Button):
    def __init__(self, master=None, **kwargs):
        tk.Button.__init__(self, master, 
            background = 'blue',
            foreground = 'white', 
            font = 'Helvetica 8 bold',
            **kwargs)

self.btn = Justine(text = 'Hello')
...