How can I move the radiator text label under a button in Python Tkinter?

I am wondering if there is a way to move the label text of a radio object to another area, for example. below the actual button.

The following is an example of several radio objects that fit using the grid I use:

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

Below is a picture of the frame when you run the code:

As you can see, the default should be on the side of the buttons, but I'm looking for a way to move the text below, I can not find any solutions on this!

Thanks Raj

+5
source share
3 answers

My thought is to try to make changes to the ttk.RadioButton layout elements or element. See http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-layouts.html .

The layout of its element seems to consist of a label inside the focus, inside the indicator, which is inside the indentation (see the rbLayout variable below). The Radiobutton.indicator option parameter remains aloof. The Radiobutton.label binding option is displayed blank. I think that changing any of these options may get what you want. You also need to add the option "style = your_customed_stylename" to your ttk.Radiobutton declaration.

 >>> 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'> 

Update:

  • I think the rbLayout variable shows that by default Radiobutton.padding contains two children, i.e. Radiobutton.indicator and Radiobutton.focus, and they are located on the left side of Radiobutton.padding. Moreover, Radiobutton.focus contains Radiobutton.label. Correction to my earlier explanation.
  • To achieve the described layout, I think that the Radiobutton.indicator "Side" should be set to "top", and the "sticky" key should be set to 'n'. In addition, the side key of "Radiobutton.focus" should be set to "bottom" and "sticky" should be "s".
  • I created a script to make changes. See below code. However, this did not work. I am surprised that the raster plan cannot be changed. They did not understand why this did not work.

I hope someone more knowledgeable can explain why the amendments to the layout of the Radiobutton elements have not changed to the required layout.

 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) 

Update 2: SOLUTION

 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 '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 upper indicator and lower mark

Thanks a lot :) j_4321 for his latest solution based on my proposed approach. I applied it (see above) to my previous code, and it works. I like to highlight the following:

  • My code shows the changes made to the default Radiobutton style layout "TRadiobutton" , instead of creating a new style with a modified layout. The advantage of this difference seems to be overcome by mentioning the flaws of the j_4321 2nd solution. That is, it works on all ttk themes ('clam', 'alt', 'default', 'classic') , and not just on 'clam' and 'alt'. At least this works on my Linux 16.04 platform.
  • The error in my previous code was that I created a new instance of s.layout () (i.e. m = s.layout ()) and changed its layout instead of actually changing the default layout of the Radiobutton s.layout ('TRadiobutton style '). I learned from j_4321's solution that you can change the default style layout by adding the changed widget layout details as a second term in tuple ttk.Style.layout (default style name for the widget) i.e. ttk.Style.layout (the default style name for the widget, for example, "TRadiobutton", [modified widget layout information]) .
  • To change the position of the Radiobutton indicator displayed at the top of its label, you need to change the value of the "Radiobutton.indicator" side to "top" . Changes to the Radiobutton.focus side value did not affect Radiobutton's layout.
+1
source

It is not possible to set the text position in the radio object, so the easiest workaround I can come up with is to delete the text of the radio object and put a shortcut over it.

Also, I would prefer to inherit the MainGUI class from Tk instead of Frame , so you don't need to create a root window in the if __name__ == '__main__': section, but this is just a suggestion.

 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

Note: to get this image, I also used ttk.Style to get a more pleasant result on Linux.

+4
source

As suggested by Sun Bear, another way to get the radioobutton shortcut under the button is to set the ttk style:

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

However, this does not work with all ttk themes. It works with clam and alt, but gives buttons that cannot be selected using the classic and default linux.

+3
source

Source: https://habr.com/ru/post/1262531/


All Articles