Abbas
Abbas

Reputation: 7

Checkbuttons not properly aligning in Tkinter

I am a Biological Engineering student working on a Capstone project in my university, and part of this project requires a little bit of coding. None of our group members knew how to code, so I've taken it upon myself to learn python and attempt to create a GUI using Tkinter. Given the reason for coding, I am extremely new to programming and thus, as a forewarning, my code is probably rather poorly written.

So to get to the point; I am having a problem getting my Checkbuttons to properly align. Essentially what happens is that the first Checkbutton group is aligned on rows 3-6 (I think, not 100% sure but they are where I want them) in column 0. I then created a second Checkbutton group in column 1, and I want the Checkbuttons to begin back at row 3-whatever, but instead they start at row 7 and span until whenever. This happens for each subsequent Checkbutton group I make.

The code is as follows:

import sys
from Tkinter import *
import tkMessageBox
import tkFileDialog
from PIL import ImageTk, Image


root = Tk()
root.geometry('900x700')
root.title('IBID 2.0')

ilabel1 = Label(root, text=' Measurement',font=("Bold",18)).grid(row=1,column=0)
datatype = {'Joint Angle' : 0,
         'Joint Acceleration' : 0,
         'Ground Reaction Force' : 0,
         'Muscle Activation' : 0
}
for measure in datatype:
    datatype[measure] = IntVar()
    dt_cb = Checkbutton(root, text=measure, variable=datatype[measure])
    dt_cb.grid(column=0, sticky='W', padx=20)


ilabel2 = Label(root, text='Muscle Group(s)',font=    ("Bold",18),padx=30).grid(row=1,column=1)

emg_groups = {'Quadriceps' : 0,
              'Hamstrings' : 0,
              'Calves' : 0
}

for measure in emg_groups:
    emg_groups[measure] = IntVar()
    emg_cb = Checkbutton(root, text=measure, variable=emg_groups[measure])
    emg_cb.grid(column=1, sticky='W', padx=20)


ilabel3 = Label(root, text='Ground Reaction Force',font=("Bold",18),padx=30).grid(row=1,column=2)

grf_groups = {'Ground Reaction Force' : 0,
              'Gait' : 0,
}

for measure in grf_groups:
    grf_groups[measure] = IntVar()
    grf_cb = Checkbutton(root, text=measure, variable=grf_groups[measure])
    grf_cb.grid(column=2, sticky='W', padx=40)

I did find a workaround where instead of using lists to create my Checkbuttons, I went ahead and made each button individually. I thought I might be able to clean up the code a little bit using lists, though I cannot find a way to put them all on the same line, I suppose. If I specify a row in the .grid(), then the options overlap one another.

Upvotes: 0

Views: 922

Answers (1)

MrAlexBailey
MrAlexBailey

Reputation: 5289

Every time you call grid() without supplying a row Tkinter is automatically assuming you want to add it to a new row at the bottom:

wdgt.grid(row=0, column=0)
wdgt.grid(column=1)         # row=1 is assumed here

Instead, you'll need to supply the row numbers to the new widgets you're trying to grid:

for i, measure in enumerate(emg_groups):
    emg_groups[measure] = IntVar()
    emg_cb = Checkbutton(root, text=measure, variable=emg_groups[measure])
    emg_cb.grid(column=1, row=i+2, sticky='W', padx=20)

and:

for i, measure in enumerate(grf_groups):
    grf_groups[measure] = IntVar()
    grf_cb = Checkbutton(root, text=measure, variable=grf_groups[measure])
    grf_cb.grid(column=2, row=i+2, sticky='W', padx=40)

Using enumerate() we get a tuple on each loop of the iteration, i being a 0 indexed counter, and of course measure being the object itself. Since you started your Label() at row 1 (you may want to change to start at row 0), we'll need to add 2 to the index each time through and then grid to that row number.

Upvotes: 1

Related Questions