Мне нужно создать собственный стиль для виджетов кнопок, который имеет тот же внешний вид, что и кнопки, используя тему ttk 'clam'.
Я могу установить тему следующим образом:
s = ttk.Style()
s.theme_use('clam')
Однако, учитывая характер темы, это затем установит для всех виджетов ttk использование "моллюска".
Я хотел бы иметь возможность настроить определенные кнопки ttk для использования внешнего вида моллюска, а другие - использовать ttk по умолчанию.
Я попытался просмотреть макеты и конфигурации "TButton", пока используется тема моллюска, но кажется, что тема представляет собой набор стилей, и я не уверен, как "сопоставить" пользовательский стиль на основе стиля кнопки моллюска. .
Ответ 1 · рейтинг 4 · James Kent
используя этот код:
import Tkinter as tk
import ttk
def get_element_details(style):
print('element: %s' % style)
print('option: %s' % str(s.element_options(style)))
layout = s.layout(style)
for elem, elem_dict in layout:
get_sub_element_details(elem, elem_dict)
print(layout)
def get_sub_element_details(elem, _dict, depth=1):
print('%selement: %s' % (''.join(['\t' for i in range(depth)]), elem))
for key in _dict:
if key != 'children':
print('%s%s: %s' % (''.join(['\t' for i in range(depth+1)]), key, _dict[key]))
print('%soption: %s' % (''.join(['\t' for i in range(depth+1)]), s.element_options(elem)))
if 'children' in _dict:
for child, child_dict in _dict['children']:
get_sub_element_details(child, child_dict, depth+1)
root = tk.Tk()
widget = ttk.Button(root, text='test')
widget.grid(sticky='nesw')
style = widget.winfo_class()
s = ttk.Style()
print(s.theme_use())
print('normal theme')
get_element_details(style)
print('\nclam theme')
s.theme_use('clam')
get_element_details(style)
вы можете получить подробную информацию обо всех параметрах макета и конфигурации виджета. с родной темой на моем ящике (xp) я получаю этот вывод:
element: TButton
option: ()
element: Button.button
sticky: nswe
option: ()
element: Button.focus
sticky: nswe
option: ()
element: Button.padding
sticky: nswe
option: ('-padding', '-relief', '-shiftrelief')
element: Button.label
sticky: nswe
option: ('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify', '-wraplength', '-embossed', '-image', '-stipple', '-background')
и с темой моллюска я получаю:
element: TButton
option: ()
element: Button.border
border: 1
sticky: nswe
option: ('-bordercolor', '-lightcolor', '-darkcolor', '-relief', '-borderwidth')
element: Button.focus
sticky: nswe
option: ('-focuscolor', '-focusthickness')
element: Button.padding
sticky: nswe
option: ('-padding', '-relief', '-shiftrelief')
element: Button.label
sticky: nswe
option: ('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify', '-wraplength', '-embossed', '-image', '-stipple', '-background')
обратите внимание, что в теме моллюска есть элемент Button.border с параметрами, тогда как в нативной теме есть элемент Button.button без параметров.
вы можете сохранить макет из темы моллюска (либо во время записи, либо вы можете получить его во время выполнения, загрузив тему моллюска, извлекая макет, затем переключив тему обратно и загрузив макет обратно) и использовать это для стилизации кнопки.
РЕДАКТИРОВАТЬ теоретически это должно работать:
import Tkinter as tk
import ttk
root = tk.Tk()
style = 'TButton'
s = ttk.Style()
#s.theme_use('clam')
#get_element_details(style)
clambuttonlayout = [('Button.border', {'border': '1', 'children': [('Button.focus', {'children': [('Button.padding', {'children': [('Button.label', {'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})], 'sticky': 'nswe'})]
s.layout('clam.TButton', clambuttonlayout)
b1 = ttk.Button(root, text="Button 1", style='clam.TButton')
b1.grid()
b2 = ttk.Button(root, text="Button 2", style='TButton')
b2.grid()
root.mainloop()
однако по какой-то причине, когда я это делаю, текст больше не появляется на первой кнопке... если я выясню это, я снова отредактирую.