如何在Python Tkinter中的按钮下方移动单选按钮的文本标签?

时间:2017-01-09 15:26:15

标签: python tkinter radio-button

我想知道是否有办法将radiobutton的标签文本移动到不同的区域,例如低于实际按钮。

以下是使用我正在使用的网格放置的几个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

3 个答案:

答案 0 :(得分:4)

没有选项可以在单选按钮中设置文本位置,因此我能想到的最简单的解决方法是删除单选按钮文本并在其下面放置一个标签。

此外,我宁愿让MainGUI类继承自Tk而不是Frame,这样您就不必在if __name__ == '__main__':中创建根窗口部分,但这只是一个建议。

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

Result

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

答案 1 :(得分:3)

正如Sun Bear建议的那样,在按钮下方获取单选按钮标签的另一种方法是自定义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中提供了无法使用经典默认选择的按钮。 / p>

答案 2 :(得分:1)

我的想法是尝试修改ttk.RadioButton的布局元素或元素的选项。见http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-layouts.html

其元素的布局似乎由一个标签组成,该标签位于焦点内部,即内部指示符,位于填充内部(参见下面的变量rbLayout)。 Radiobutton.indicator的选项值保留。 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'>

<强>更新

  1. 我认为rbLayout变量默认显示 Radiobutton.padding包含两个子元素,即 Radiobutton.indicator和Radiobutton.focus,它们被定位 在Radiobutton.padding的左侧。此外, Radiobutton.focus包含Radiobutton.label。纠正我的 早先的解释。
  2. 为了实现所描述的布局,我认为是Radiobutton.indicator的 &#39;侧&#39; key应该有价值&#39; top&#39;和&#39;粘&#39;关键应该有 价值&#39; n&#39;。此外,Radiobutton.focus&#39; side&#39;关键应该有 价值&#39;底部&#39;和&#39;粘&#39;价值应该是&#39;。
  3. 我创建了一个脚本来实现更改。见下面的代码。 但是,它没有用。我对radiobutton布局感到惊讶 没变。不明白为什么它不起作用。
  4. 希望有更多知识渊博的人能够解释为什么对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)
    

    Radiobutton with top indicator and bottom label

    非常感谢:)给j_4321建立了基于我建议方法的最新解决方案。我已经实现了它(见上文)到我以前的代码,它的工作原理。我想强调以下内容:

    1. 我的代码显示对Radiobutton的默认样式&#39; TRadiobutton&#39; 的布局所做的更改,而不是创建具有更改布局的新样式。这种差异的优势似乎克服了j_4321第二解决方案的缺点。也就是说,适用于所有ttk主题(&#39; clam&#39;,&#39; alt&#39;,&#39;默认&#39;,&#39; classic&#39;)< / strong>而不仅仅是&#39; clam&#39;和&#39; alt&#39;。至少这适用于我的Linux 16.04平台。
    2. 我之前的代码中的错误是我创建了一个新的s.layout()实例(即m = s.layout())并更改了它的布局,而不是实际更改了它的布局默认Radiobutton样式s.layout(&#39; TRadiobutton&#39;)。我从j_4321的解决方案中了解到,可以通过添加窗口小部件布局的更改细节作为元组ttk.Style中的第二个术语来更改默认样式的布局。布局(窗口小部件的默认样式名称),即 ttk.Style.layout(窗口小部件的默认样式名称,例如&#39; TRadiobutton&#39;,[更改窗口小部件的布局详细信息] ) 即可。
    3. 要将Radiobutton指示器的位置更改为显示在其标签的顶部,将更改为Radiobutton.indicator&#39; side&#39;价值到&#39; top&#39; 仅需要。改变Radiobutton.focus&#39; s&#39;价值对Radiobutton的布局没有影响。