Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter configure columnwidth

Tags:

python

tkinter

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

like image 308
Evilunclebill Avatar asked Dec 26 '12 19:12

Evilunclebill


People also ask

How do I add columns and rows to a Tkinter grid?

Tkinter provides you with two methods for configuring grid rows and columns: container.columnconfigure (index, weight) container.rowconfigure (index, weight) Code language: CSS (css) The columnconfigure () method configures the column index of a grid.

How do I position widgets on a grid In Tkinter?

Before positioning widgets on a grid, you’ll need to configure the rows and columns of the grid. Tkinter provides you with two methods for configuring grid rows and columns: The columnconfigure () method configures the column index of a grid. The weight determines how wide the column will occupy, which is relative to other columns.

How to calculate the actual width of a Tkinter entry?

The actual width of the Tkinter Entry is 2*ipadx + Default Entry width, similarly the actual width of Entry is 2*ipady + Default Entry height. As you could see, because entryExample2 has ipadx as 20 meanwhile ipadx of entryExample1 is by default 0, therefore, the width of entryExample2 is 40 pixels wider than entryExample1.

What is tkinter8?

Tkinter8.5 reference: a GUI for Python 4.3.  Configuring column and row sizes Unless you take certain measures, the width of a grid column inside a given widget will be equal to the width of its widest cell, and the height of a grid row will be the height of its tallest cell.


1 Answers

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.

like image 196
Bryan Oakley Avatar answered Oct 19 '22 15:10

Bryan Oakley