Resizing panel/frame/treeview dynamically

Question:

When I resize the window I would like the frame, panel and treeview to resize with it.
As shown in the screenshot, this is not the case with my current setup.

I have tried to use this but it makes no difference.

    n.pack(expand=1, fill="both")
    f1.columnconfigure((0, 1), weight=1)
    f1.rowconfigure((0, 1), weight=1)

I have also tried to use Grid.columnconfigure(root, 0, weight=1) as found here on SO but Grid has no columnconfigure() so I wonder how that should work.

from tkinter import *
from tkinter import ttk


def createmenu(win):
    top = Menu(win)
    win.config(menu=top)
    file = Menu(top)
    file.add_command(label='Quit', command=win.quit, underline=0)
    top.add_cascade(label='File', menu=file, underline=0)


def panels(parent):
    n = ttk.Notebook(parent)
    f1 = ttk.Frame(n)
    f2 = ttk.Frame(n)

    n.add(f1, text='Mods')
    n.add(f2, text='Modfiles')

    tree = ttk.Treeview(f1, columns=('mod_id', 'version', 'category_id', 'insert_timestamp'))
    tree.grid(row=4, columnspan=6, sticky='nsew')
    tree.insert(
        '',
        'end',
        iid='id1',
        text='sometext',
        values=(12, 24, 35, 67)
    )


root = Tk()
root.title("Xyrim")
root.geometry("")
print("Windowing system: " + root.tk.call('tk', 'windowingsystem'))

root.option_add('*tearOff', FALSE)

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

createmenu(root)

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

panels(mainframe)

for child in mainframe.winfo_children():
    child.grid_configure(padx=5, pady=5)

root.mainloop()

enter image description here

Asked By: Thijs

||

Answers:

It seems you do not really know what you are doing in your code.

##for child in mainframe.winfo_children():
##    child.grid_configure(padx=5, pady=5)

This code does not just add padding, grid_configure is a synonym for grid and therefore the grid default values apply, except for those that are defined. So it is no surprise it does not work in the way you would like, you never specified it.

Fot this reason it is good practice to work with explicit, rather than implicit instructions. If you want to use default values for keywords you can define a dictionary for.

mainframe_defaults = {
    'padx' : 5,
    'pady' : 5}

Don’t use wildcard imports, such as from tkinter import * you end up with a bunch of reserved names and overwriting them can cause trouble. Name conflicts is another reason, to avoid it, or simply because you don’t know if the library will add additional names in the next update, that breaks your application. So rather do import tkinter as tk.

Next you should use the geometry manager that fits the best to your task. pack makes it easy to have just a couple of widgets next to each other and have them resized with the master, especially if it`s just a single widget in the container.

n = ttk.Notebook(parent)
n.pack(fill = tk.BOTH, expand=True)

The last advice for you, apply grid_rowconfigure or grid_columnconfigure on the master the master of the widget you desire to consume extra space and don’t forget to specify the right column or row.

f1.grid_columnconfigure(0, weight=1)
f1.grid_rowconfigure(4, weight=1)

Your full code looks like this:

import tkinter as tk
from tkinter import ttk


def createmenu(win):
    top = tk.Menu(win)
    win.config(menu=top)
    file = tk.Menu(top)
    file.add_command(label='Quit', command=win.quit, underline=0)
    top.add_cascade(label='File', menu=file, underline=0)


def panels(parent):
    n = ttk.Notebook(parent)
    n.pack(fill = tk.BOTH, expand=True, **mainframe_defaults)
    f1 = ttk.Frame(n)
    f2 = ttk.Frame(n)

    n.add(f1, text='Mods')
    n.add(f2, text='Modfiles')

    tree = ttk.Treeview(f1, columns=('mod_id', 'version', 'category_id', 'insert_timestamp'))
    tree.grid(row=4, columnspan=6, sticky='nsew')
    tree.insert(
        '',
        'end',
        iid='id1',
        text='sometext',
        values=(12, 24, 35, 67)
    )
    f1.grid_columnconfigure(0, weight=1)
    f1.grid_rowconfigure(4, weight=1)


root = tk.Tk()
root.title("Xyrim")
root.geometry("")
print("Windowing system: " + root.tk.call('tk', 'windowingsystem'))

root.option_add('*tearOff', False)

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky='nswe')
mainframe_defaults = {
    'padx' : 5,
    'pady' : 5}

createmenu(root)

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

panels(mainframe)
Answered By: Thingamabobs
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.