Home > Back-end >  Grid items from a list in pairs tkinter
Grid items from a list in pairs tkinter

Time:10-31

I am trying to create a grid of 14 radiobuttons from a list of 14 items, I would like the buttons to be arranged in 7 pairs, so far, what I am getting is this with the following code:

import tkinter as tk
from tkinter import ttk
from tkinter.ttk import *

root = tk.Tk()
root.geometry('400x400')
bs = ['Skin and Soft Tissue', 'Bone and Joint', 'Central Nervous System', 'Genito- 
Urinary', 'Gastrointestinal', 'Cardiovascular', 'ENT', 'Gynaecological Infections', 
'Intravascular access Device', 'Sexual Transmitted Infections', 'Pregancy Associated 
Sepsis', 'Respiratory', 'Lyme Disease', 'Splenectomy/Functional Asplenia']
n = tk.StringVar()
nrows = 7
ncols = 2
nitems = 14
for r in range(nrows):
  for c in range(ncols):
    for body in range(len(bs)):
        tk.Radiobutton(root, text = bs[r], var = n, value = bs[r]).grid(row = 
        r, column = c)
root.mainloop()

What I am getting so far is this

enter image description here

My question is, how do I get python to iterate every item on the list so I get all radiobuttons in 7 pairs all with their respective names?

CodePudding user response:

try this

for r in range(nrows):
    for c in range(ncols):
        tk.Radiobutton(root, text = bs[r*ncols c], var = n, value = bs[r*ncols c]).grid(row = r, column = c)

it uses the formula r*ncols c to find the appropriate item in the bs list. If this is not intuitive then do some calculations to test it, eg

r   c   r*2 c
0   0       0
0   1       1
1   0       2
1   1       3
2   0       4
2   1       5

so far what I get is this:screenshot

CodePudding user response:

Here is an example of how to position items in set rows and columns:

import tkinter as tk

bs = ['Skin and Soft Tissue', 'Bone and Joint', 'Central Nervous System',
      'Genito-Urinary', 'Gastrointestinal', 'Cardiovascular', 'ENT',
      'Gynaecological Infections','Intravascular access Device',
      'Sexual Transmitted Infections', 'Pregancy Associated Sepsis',
      'Respiratory', 'Lyme Disease', 'Splenectomy/Functional Asplenia']


root = tk.Tk()
root.geometry('400x400')

n_rows = 7
n_cols = 2

n = tk.StringVar(value=' ')
for index, text in enumerate(bs):
    c = index // n_rows
    if c   1 > n_cols:
        break
    tk.Radiobutton(
        root, text=text, var=n, value=text
    ).grid(row=index % n_rows, column=c, sticky='w')

root.mainloop()

First note that this loop prioritizes rows i.e. it first fills all the rows before going to the next column and also if there are more items than n_cols * n_rows it will break after it has filled all set rows and columns.

Basically it uses index to detect the item index and the % (modulo) to set the row since it calculates the reminder then for example 6th index will return 6 (7th row in order) and for 13th index (last item in this case) it will also return 6 (which again is 7th row in order) because that is the remainder when dividing 13 / 7 and that is what modulo returns. The column is simply set from the index ground divided by columns so basically it increases when the column is filled up since for example 7th index (8th item in list) will do c = 7 // 7 which is 1 (2nd column) and then 13 // 7 is also 1 and so on. (also I would suggest using sticky='w' so that the checkbuttons are aligned on the left side (or whichever side you need))

CodePudding user response:

Since every answer works but dosent seem intuitiv in my opinion I add another one:

import tkinter as tk

root = tk.Tk()
root.geometry('400x400')
bs = ['Skin and Soft Tissue', 'Bone and Joint', 'Central Nervous System', 'Genito- Urinary',
      'Gastrointestinal', 'Cardiovascular', 'ENT', 'Gynaecological Infections',
      'Intravascular access Device', 'Sexual Transmitted Infections', 'Pregancy Associated Sepsis',
      'Respiratory', 'Lyme Disease', 'Splenectomy/Functional Asplenia']

n = tk.StringVar(bs[0])
skip_point=len(bs)/2 #next row by half of the size of this list

for idex,i in enumerate(bs,1): #enumerate for counter and start by 1
    widget = tk.Radiobutton(root,text=i,var=n,value=i)
    if idex <= skip_point:
        widget.grid(row=int(idex),column=0,sticky='w')
    else:
        widget.grid(row=int(idex-skip_point),column=1,sticky='w')

root.mainloop()

I terminate the skip_point and use a if statement to check for this condition. In addition I use enumerate to have a counter in my loop so I can calculate with the current index/idex. See notes in code for more details.

  • Related