我的想法是尝试修改 ttk.RadioButton 的布局元素或元素的选项。见http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-layouts.html。
其元素的布局似乎由一个标签组成,即在焦点内,即在指示器内,即在填充内(参见下面的变量 rbLayout)。 Radiobutton.indicator 的 side 选项值被保留。 Radiobutton.label 的锚选项显示为空白。我认为改变这两个选项中的任何一个都可能得到你想要的。您还必须将选项“style=your_customed_stylename”添加到您的 ttk.Radiobutton 声明中。
>>> import tkinter.ttk as ttk
>>> s = ttk.Style()
>>> rb = ttk.Radiobutton(None, text='RB1')
>>> rbClass = rb.winfo_class()
>>> rbClass
'TRadiobutton'
>>> rbLayout = s.layout('TRadiobutton')
>>> rbLayout
[('Radiobutton.padding', {'sticky': 'nswe', 'children': [('Radiobutton.indicator', {'sticky': '', 'side': 'left'}), ('Radiobutton.focus', {'children': [('Radiobutton.label', {'sticky': 'nswe'})], 'sticky': '', 'side': 'left'})]})]
>>> type(rbLayout)
<class 'list'>
更新:
- 我认为 rbLayout 变量显示默认情况下
Radiobutton.padding 包含两个子元素,即
Radiobutton.indicator 和 Radiobutton.focus,它们是定位的
在 Radiobutton.padding 的左侧。此外,
Radiobutton.focus 包含 Radiobutton.label。更正我的
较早的解释。
- 为了实现所描述的布局,我认为 Radiobutton.indicator 的
'side' 键应该有值 'top' 和 'sticky' 键应该有
值'n'。此外,Radiobutton.focus 的 'side' 键应该有
值 'bottom' 和 'sticky' 值应该是 's'。
- 我创建了一个脚本来实施这些更改。请参见下面的代码。
但是,它没有用。我很惊讶单选按钮布局
没变。不明白为什么它不起作用。
希望有更多知识的人能解释一下为什么对 Radiobutton 元素布局的修改没有更改为所需的布局。
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
root.geometry("300x100")
s = ttk.Style()
m = s.layout('TRadiobutton')
print('TRadiobutton.Layout : Default')
print(m , "\n")
# Change to default Radiobutton.indicator elements
list(list(m[0])[1]['children'][0])[1]['side'] = 'top'
list(list(m[0])[1]['children'][0])[1]['sticky'] = 'n'
# Change to default Radiobutton.focus elements
list(list(m[0])[1]['children'][1])[1]['side']='bottom'
list(list(m[0])[1]['children'][1])[1]['sticky']='s'
print('TRadiobutton.Layout : Amended')
print(m, "\n")
frame1 = ttk.Frame(root)
frame1.grid()
rb1 = ttk.Radiobutton(frame1, text="Button 1")
rb1.grid()
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
更新 2:解决方案
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
root.geometry("300x100")
s = ttk.Style()
s.theme_use('default')
print('TRadiobutton.Layout : Default')
print(s.layout('TRadiobutton'), "\n")
s.layout('TRadiobutton',
[('Radiobutton.padding',
{'children':
[('Radiobutton.indicator', {'side': 'top', 'sticky': ''}), # Just need to change indicator's 'side' value
('Radiobutton.focus', {'side': 'left',
'children':
[('Radiobutton.label', {'sticky': 'nswe'})],
'sticky': ''})],
'sticky': 'nswe'})])
print('TRadiobutton.Layout : Amended')
print(s.layout('TRadiobutton'), "\n")
frame1 = ttk.Frame(root)
frame1.grid()
rb1 = ttk.Radiobutton(frame1, text="Button 1")
rb1.grid()
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
非常感谢 :) j_4321 根据我建议的方法构建的最新解决方案。我已经在我之前的代码中实现了它(见上文)并且它可以工作。我想强调以下几点:
- 我的代码显示对单选按钮的默认样式“TRAdiobutton”的布局所做的更改,而不是创建具有更改布局的新样式。这种差异的优势似乎克服了 j_4321 第二种解决方案提到的缺点。也就是说,它适用于所有 ttk 主题('clam'、'alt'、'default'、'classic'),而不仅仅适用于 'clam' 和 'alt'。至少这适用于我的 Linux 16.04 平台。
- 我之前的代码中的错误是我创建了一个新的 s.layout() 实例(即 m = s.layout())并更改了它的布局,而不是实际更改默认 Radiobutton 样式 s 的布局.layout('TRAdiobutton')。我从 j_4321 的解决方案中了解到,可以通过添加小部件布局的更改细节作为元组 ttk.Style.layout(小部件的默认样式名称)中的第二项来更改默认样式的布局,即 ttk.Style.layout(widget 的默认样式名称 eg 'TRAdiobutton', [changed layout details of widget]).
- 要将 Radiobutton 指示器的位置更改为显示在其标签顶部,将 Radiobutton.indicator 的“side”值更改为“top”只需要。更改 Radiobutton.focus 的“side”值对 Radiobutton 的布局没有影响。