Python Forum
[Tkinter] Settting Default Values for grid
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Settting Default Values for grid
#1
I am finding myself repeating the same options for grid which is getting tedious and error prone. Is there no way to set defaults for grid to make the code shorter and less tedious? TIA.
Reply
#2
Less tedious than what? Show your work please.
Reply
#3
Just one right now.

label1=tk.Label(top,text='Phone',justify=tk.LEFT).grid(row=rw,column=0,pady=5)
I have to add 'pady=5' to every grid call and there are many and will be more.
Reply
#4
You could make your own class.
import tkinter as tk

class MyLabel(tk.Label):
    '''A Label with padding that takes on parents background color'''
    def __init__(self, parent=None, text='', row=0, col=0, padx=5, pady=5, **kwargs):
        bg = None if parent is None else parent['bg']
        super().__init__(parent, text=text, bg=bg, **kwargs)
        self.grid(row=row, column=col, padx=padx, pady=pady)

root = tk.Tk()
root.configure(bg='black')
MyLabel(root, "Red", 0, 0, fg='blue')
MyLabel(root, "Blue", 1, 1, fg='green')
MyLabel(root, "Green", 2, 2, fg='red')

root.mainloop()
You could write a helper function.
import tkinter as tk

def new_label(parent=None, text='', row=0, col=0, padx=5, pady=5, **kwargs):
    bg = None if parent is None else parent['bg']
    label = tk.Label(parent, text=text, bg=bg, **kwargs)
    label.grid(row=row, column=col, padx=padx, pady=pady)
    return label

root = tk.Tk()
root.configure(bg='black')
new_label(root, "Red", 0, 0, fg='blue')
new_label(root, "Blue", 1, 1, fg='green')
new_label(root, "Green", 2, 2, fg='red')

root.mainloop()
You could make your controls in a loop.
import tkinter as tk

root = tk.Tk()
root.configure(bg='black')
for index, config in enumerate(zip(('Red', 'Blue', 'Green'), ('blue', 'green', 'red'))):
    text, fg = config
    label = tk.Label(root, text=text, fg=fg, bg='black')
    label.grid(row=index, column=index, padx=5, pady=5)

root.mainloop()
Reply
#5
Thanks. That works fine for a label but not all the other widgets. I'll think about how to generalize it for any widget.
Reply
#6
You could make a mixin class that adds the features you want for every widget and use that to make your own mixin versions of Label, Entry, Button...

Maybe a better solution for you is to write a Frame subclass that takes care of the layout responsibilities.
import tkinter as tk

class Grid(tk.Frame):
    '''A tk.Frame for lazy typers'''
    def __init__(self, parent=None, bg=None, **kwargs):
        if bg is None and parent is not None:
            bg = parent['bg']
        self.bg = bg
        super().__init__(parent, bg=self.bg, **kwargs)
        self.row = 0
        self.column = 0
        self.padx = 5
        self.pady = 5

    def add(self, widget, row=None, column=None, padx=None, pady=None, bg=None):
        if row is not None:
            self.row = row
        if column is not None:
            self.column = column
        if padx is not None:
            self.padx = padx
        if pady is not None:
            self.pady = pady
        if bg is not None:
            self.bg = bg
        widget['bg'] = self.bg
        widget.grid(row=self.row, column=self.column, padx=self.padx, pady=self.pady)
        return self

root = tk.Tk()
root.configure(bg='black')
grid = Grid(root, bg='black')
grid.pack()
grid.add(tk.Label(grid, text='Red', fg='blue'), row=0, column=0) \
    .add(tk.Label(grid, text='Blue', fg='green'), row=1) \
    .add(tk.Label(grid, text='Green', fg='red'), row=2) \
    .add(tk.Entry(grid, width=5), row=0, column=1, bg='yellow') \
    .add(tk.Entry(grid, width=5), row=1) \
    .add(tk.Entry(grid, width=5), row=2)

root.mainloop()
You could also repack everything after you create the widgets.
import tkinter as tk

root = tk.Tk()
root.configure(bg='black')

tk.Label(root, text='Red', fg='blue').grid(row=0, column=0)
tk.Label(root, text='Blue', fg='green').grid(row=1, column=0)
tk.Label(root, text='Green', fg='red').grid(row=2, column=0)
tk.Entry(root, width=5).grid(row=0, column=1)
tk.Entry(root, width=5).grid(row=1, column=1)
tk.Entry(root, width=5).grid(row=2, column=1)

for child in root.winfo_children():
    child.grid_configure(padx=5, pady=5)
    if isinstance(child, tk.Label):
        child['bg'] = 'black'
    elif isinstance(child, tk.Entry):
        child['bg'] = 'yellow'

root.mainloop()
Or you could set your own grid method.
import tkinter as tk

print(tk.Label.__bases__)
print(tk.Entry.__bases__)

root = tk.Tk()

def mygrid(self, row, column, padx=10, pady=5):
    self.grid(row=row, column=column, padx=padx, pady=pady)

setattr(tk.Widget, 'mygrid', mygrid)

tk.Label(root, text='Red', fg='blue').mygrid(row=0, column=0)
tk.Label(root, text='Blue', fg='green').mygrid(row=1, column=0)
tk.Label(root, text='Green', fg='red').mygrid(row=2, column=0)
tk.Entry(root, width=5).mygrid(row=0, column=1)
tk.Entry(root, width=5).mygrid(row=1, column=1)
tk.Entry(root, width=5).mygrid(row=2, column=1)

root.mainloop()
What I am trying to show is that if you have a regular pattern that you use when writing code, you can create tools that support that pattern. I don't write much tkinter code, and I think the tkinter object model is rather clunky, but it didn't take me long to come up with half a dozen ways to speed up how I could write tkinter code. You should review your code, look at your work patterns and think about what you could make that would speed up what you do.
Reply
#7
Thanks, that helps.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Default Values for radiobuttons xuraax 2 3,871 May-17-2020, 06:43 PM
Last Post: xuraax

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020