在Python Tkinter中,如何将radiobutton的文本标签移动到按钮下方?

在Python Tkinter中,如何将radiobutton的文本标签移动到按钮下方?,python,tkinter,radio-button,Python,Tkinter,Radio Button,我想知道是否有办法将radiobutton的标签文本移动到其他区域,例如实际按钮下方 下面是使用我正在使用的网格放置的几个单选按钮的示例: from tkinter import * from tkinter import ttk class MainGUI(Frame): def __init__(self, parent): self.parent = parent Frame.__init__(self, parent, background=

我想知道是否有办法将radiobutton的标签文本移动到其他区域,例如实际按钮下方

下面是使用我正在使用的网格放置的几个单选按钮的示例:

from tkinter import *
from tkinter import ttk


class MainGUI(Frame):

    def __init__(self, parent):
        self.parent = parent
        Frame.__init__(self, parent, background="white")
        self.mainframe = ttk.Frame(root, padding="8 8 12 12")
        self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        self.mainframe.columnconfigure(0, weight=1)
        self.mainframe.rowconfigure(0, weight=1)
        ttk.Radiobutton(self.mainframe, text="Button 1", value=0).grid(column=1, row=2)
        ttk.Radiobutton(self.mainframe, text="Button 2", value=1).grid(column=2, row=2)
        ttk.Radiobutton(self.mainframe, text="Button 3", value=2).grid(column=3, row=2)
        ttk.Radiobutton(self.mainframe, text="Button 4", value=3).grid(column=4, row=2)

if __name__ == '__main__':
    root = Tk()
    root.geometry("300x100")
    app = MainGUI(root)
    root.mainloop()
下面是运行代码时的帧图像:

正如你所看到的,默认设置是在按钮的一侧,但是我正在寻找一种方法来移动下面的文本,我似乎找不到任何解决这个问题的方法


谢谢,Raj

在radiobutton中没有设置文本位置的选项,因此我能想到的最简单的解决方法是删除radiobutton文本并在其下方放置标签

此外,我宁愿让
MainGUI
类继承自
Tk
,而不是
Frame
,这样您就不必在
中创建一个根窗口,如果
部分的话,但这只是一个建议

from tkinter import *
from tkinter import ttk

class MainGUI(Tk):

    def __init__(self):
        Tk.__init__(self)
        self.geometry("300x100")
        self.configure(background="white")
        self.mainframe = ttk.Frame(self, padding="8 8 12 12")
        self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        self.mainframe.columnconfigure(0, weight=1)
        self.mainframe.rowconfigure(0, weight=1)
        ttk.Radiobutton(self.mainframe,  value=0).grid(column=1, row=2)
        ttk.Label(self.mainframe, text="Button 1").grid(column=1, row=3, padx=4)
        ttk.Radiobutton(self.mainframe,  value=1).grid(column=2, row=2)
        ttk.Label(self.mainframe, text="Button 2").grid(column=2, row=3, padx=4)
        ttk.Radiobutton(self.mainframe,  value=2).grid(column=3, row=2)
        ttk.Label(self.mainframe, text="Button 3").grid(column=3, row=3, padx=4)
        ttk.Radiobutton(self.mainframe,  value=3).grid(column=4, row=2)
        ttk.Label(self.mainframe, text="Button 4").grid(column=4, row=3, padx=4)
        self.mainloop()

if __name__ == '__main__':
    app = MainGUI()


备注:为了获得这张图片,我还使用了
ttk.Style
在linux中获得了更好的结果。

我的想法是尝试修改ttk.RadioButton的布局元素或元素的选项。看

其元素的布局似乎由一个标签组成,该标签位于焦点内,该标签位于指示器内,该标签位于填充内(请参见下面的变量rbLayout)。单选按钮。指示器的侧选项值为左。Radiobutton.label的定位选项显示为空。我认为改变这两个选项中的任何一个都可能得到你想要的。您还必须在ttk.Radiobutton声明中添加选项“style=your_customed_stylename”

>>> 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'>
更新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基于我建议的方法提出了最新的解决方案。我已经在以前的代码中实现了它(见上文),并且它可以正常工作。我想强调以下几点:

  • 我的代码显示对Radiobutton默认样式“TRadiobutton”的布局所做的更改,而不是使用更改的布局创建新样式。这种差异的优点似乎克服了j_4321第二种解决方案中提到的缺点。也就是说,它适用于所有ttk主题(“clam”、“alt”、“default”、“classic”)而不仅仅是“clam”和“alt”。至少这在我的Linux16.04平台上是可行的
  • 我以前的代码中的错误是,我创建了一个s.layout()的新实例(即m=s.layout())并更改了它的布局,而不是实际更改默认Radiobutton样式s.layout(“TRadiobutton”)的布局。我从j_4321的解决方案中了解到,可以通过在元组ttk.style.layout(小部件的默认样式名称)中添加小部件布局的更改细节作为第二项来更改默认样式的布局,即ttk.style.layout(小部件的默认样式名称,例如“TRadiobutton”,[changed layout details of widget])
  • 要将Radiobutton指示器的位置更改为显示在其标签顶部,请更改为Radiobutton。指示器的“侧”值仅需要更改为“顶部”。对Radiobutton的更改。焦点的“侧”值对Radiobutton的布局没有影响

  • 正如Sun Bear所建议的,另一种获取按钮下方radiobutton标签的方法是自定义ttk样式:

    from tkinter import *
    from tkinter import ttk
    
    class MainGUI(Tk):
    
        def __init__(self):
            Tk.__init__(self)
            self.geometry("300x100")
            self.configure(background="white")
            self.mainframe = ttk.Frame(self, padding="8 8 12 12")
            self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
            self.mainframe.columnconfigure(0, weight=1)
            self.mainframe.rowconfigure(0, weight=1)
            style = ttk.Style(self)
            style.theme_use('clam')
            # create custom radiobutton style layout
            style.layout('CustomRadiobutton', 
                         [('Radiobutton.padding',
                           {'children': 
                               [('Radiobutton.indicator', 
                                 {'side': 'top', 'sticky': ''}), # changed side from left to top
                                ('Radiobutton.focus',
                                 {'children': [('Radiobutton.label', {'sticky': 'nswe'})],
                                  'side': 'top', # changed side from left to top
                                  'sticky': ''})],
                            'sticky': 'nswe'})])
            style.configure('TFrame', background="white")
            style.configure('CustomRadiobutton', background="white")
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 1", value=0).grid(column=1, row=2, padx=4)
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 2", value=1).grid(column=2, row=2, padx=4)
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 3", value=2).grid(column=3, row=2, padx=4)
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 4", value=3).grid(column=4, row=2, padx=4)
            self.mainloop()
    
    if __name__ == '__main__':
        app = MainGUI()
    

    但是,这并不适用于所有ttk主题。它可以与clam和alt一起工作,但提供了在linux中无法使用classic和default选择的按钮。

    问得好!欢迎使用StackOverflow:)您可能还想使用:)您需要将参数中修改后的布局传递到
    s.layout
    :请参阅我的第二个答案以获得一个工作示例。@j_4321非常感谢!我从您的解决方案中学习并更新了代码(请参阅更新2:解决方案)。另外,请注意我的新发现,它克服了您提到的限制(适用于所有ttk.风格主题)和观察(只需要更改指示器的“侧”值)。
    from tkinter import *
    from tkinter import ttk
    
    class MainGUI(Tk):
    
        def __init__(self):
            Tk.__init__(self)
            self.geometry("300x100")
            self.configure(background="white")
            self.mainframe = ttk.Frame(self, padding="8 8 12 12")
            self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
            self.mainframe.columnconfigure(0, weight=1)
            self.mainframe.rowconfigure(0, weight=1)
            style = ttk.Style(self)
            style.theme_use('clam')
            # create custom radiobutton style layout
            style.layout('CustomRadiobutton', 
                         [('Radiobutton.padding',
                           {'children': 
                               [('Radiobutton.indicator', 
                                 {'side': 'top', 'sticky': ''}), # changed side from left to top
                                ('Radiobutton.focus',
                                 {'children': [('Radiobutton.label', {'sticky': 'nswe'})],
                                  'side': 'top', # changed side from left to top
                                  'sticky': ''})],
                            'sticky': 'nswe'})])
            style.configure('TFrame', background="white")
            style.configure('CustomRadiobutton', background="white")
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 1", value=0).grid(column=1, row=2, padx=4)
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 2", value=1).grid(column=2, row=2, padx=4)
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 3", value=2).grid(column=3, row=2, padx=4)
            ttk.Radiobutton(self.mainframe, style='CustomRadiobutton',
            text="Button 4", value=3).grid(column=4, row=2, padx=4)
            self.mainloop()
    
    if __name__ == '__main__':
        app = MainGUI()