9

I have been around the docs and found 3 viable options inside the columnconfigure:

  • minsize
  • pad
  • weight

But what if you wanted to have the column as small as possible?

I have 3 checkbuttons i want to line up next to eachother.

what i found working was to:

weekly.grid(row = 2, column = 1, sticky = W)
monthly.grid(row = 2, column = 1, padx = 75, sticky = W)
yearly.grid(row = 2, column = 1, padx = 150, sticky = W)

Is there not a more "beautifull" way to do this?

(might be worth saying that when using column 2 and 3 they are seperated waaaay too much :-()

Best regards,

Casper

Evilunclebill
  • 769
  • 3
  • 9
  • 27

1 Answers1

13

The default behavior of using the grid geometry manager is that columns will be as small as possible, so you don't need to do anything (assuming you're using grid properly).

The behavior you describe where there is too much space between the elements is probably due to the fact you have other widgets in that same column which are wider. The column will default to the smallest width that will accomodate the widest item. That, or elsewhere in your code you give a non-zero weight to some of those columns that is causing them to expand.

Before I talk about a solution, let me make sure it's clear that the way you're using grid to put more than one widget in the same cell is definitely the wrong way to do it. There's absolutely no reason to resort to such a solution. A general rule of thumb is that you should never put more than one widget in a cell.

The simplest solution for you is to combine grid and pack. Put all of your checkbuttons in a frame and pack them on the left side of that frame. Then, put the frame in your grid with sticky="w". Then, no matter how big the window gets, the checkbuttons will always be stuck to the left side of their containing frame.

Note that this solution doesn't break the rule of thumb I mentioned earlier. You're only putting one widget in a cell: the frame. You can put whatever you want in that inner frame, but from the perspective of the grid there is only a single widget in each cell of the grid.

Here is a working example base on python 2.7:

import Tkinter as tk

class ExampleView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        cbframe = tk.Frame(self)
        cb1 = tk.Checkbutton(cbframe, text="Choice 1")
        cb2 = tk.Checkbutton(cbframe, text="Choice 2")
        cb3 = tk.Checkbutton(cbframe, text="Choice 3")

        cb1.pack(side="left", fill=None, expand=False)
        cb2.pack(side="left", fill=None, expand=False)
        cb3.pack(side="left", fill=None, expand=False)

        # this entry is for illustrative purposes: it
        # will force column 2 to be widget than a checkbutton
        e1 = tk.Entry(self, width=20)
        e1.grid(row=1, column=1, sticky="ew")

        # place our frame of checkbuttons in the same column
        # as the entry widget. Because the checkbuttons are
        # packed in a frame, they will always be "stuck"
        # to the left side of the cell.
        cbframe.grid(row=2, column=1, sticky="w")

        # let column 1 expand and contract with the 
        # window, so you can see that the column grows
        # with the window, but that the checkbuttons
        # stay stuck to the left
        self.grid_columnconfigure(1, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    view = ExampleView(root)
    view.pack(side="top", fill="both", expand=True)
    root.wm_geometry("400x200")
    root.mainloop()

Of course, you can also place the checkbuttons in separate columns -- which is often easiest -- but you might need to have other items in other rows span multiple columns and deal with column weights. Since it's not clear exactly what your problem is based on your description, the above solution is probably the simplest for you.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • 2
    I see. I had no idea you could combine .pack and .grid. I do indeed have a widget above the checkbuttons which is columnspanning - and that is as you write probably the reason to which my columns are as wide automaticly? Im upvotinng and accepting as this is indeed a better solution to the problem than mine was, thanks! :-) – Evilunclebill Dec 27 '12 at 11:08
  • Under what conditions is it ok to combine grid and pack? According to http://effbot.org/tkinterbook/grid.htm, they may never finish under certain conditions. – jfa Aug 12 '17 at 15:00
  • 1
    @JFA: the only requirement is that you can't use grid and pack together on widgets that have the same parent. – Bryan Oakley Aug 12 '17 at 15:11
  • >> *"The default behavior of using the grid geometry manager is that columns will be as small as possible, so you don't need to do anything".* That must come with a big bold letters disclaimer somewhere that the columns will auto-shrink only when one of the columns has its weight set to "1". If not, they'll just be uniformly sized, at least that's my observed behavior on Python 3.6.6. – Prahlad Yeri Oct 11 '22 at 06:40
  • @PrahladYeri: I don't understand your comment. Setting the weight won't cause a column to shrink. – Bryan Oakley Oct 11 '22 at 14:10
  • The problem is that you must enter the weight of at least one column on the row which will act as an expander and cause other columns to shrink. If you don't do that and let them be by default (which is 0 weight), then your widgets won't auto-shrink as each column will occupy uniform/ad-hoc width. – Prahlad Yeri Oct 11 '22 at 14:39
  • @PrahladYeri: setting the weight on one column won't cause the others to shrink. It only affects what grid does with unused space. The other columns will remain just large enough to fit their widest items. Column widths by default are neither uniform nor ad-hoc. Like this answer says, columns will always be just wide enough to fit the widest item in the column. – Bryan Oakley Oct 11 '22 at 14:47
  • I don't think they are just wide enough to fit the widest item in the column. In my experience, they took far more space than the labels and buttons that occupied them. It was only when I set one column's width to 1 that the other cols became just wide enough to fit the widest items! (i.e. auto-shrink behavior). Could I be doing something wrong here? – Prahlad Yeri Oct 11 '22 at 15:01