I have a piece of code that creates few widgets and places them in a grid (for example 3x2). When a particular event occurs, I want the grid to be redrawn, but this time the switching positions (thus creating a grid 2x3). For the sake of simplicity, I've created a sample code, where a button click does the swapping.
PROBLEM: clicking the button, the widgets get rearranged on the grid as expected, but then the window shows a "third" empty column (and symmetrically, transposing them again creates a third empty row). It is like the grid pattern remembers that there was a third column before swapping. I've tried with destroy()
ing the widgets, grid_forget()
and grid_remove()
, but still the grid pattern "remembers" the extra column/row it had. I'm suspecting the problem lies in the grid_rowconfigure
and grid_columnconfigure
that I have to call to get the resizable effect. But I'm not sure how to un-configure them... so to speak.
Does anyone know how to get the grid redrawn with only the column and rows needed for the new layout of displayed widgets?
import tkinter as tk
class TestGrid(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master, bg='white')
colors = ['cyan', 'magenta', 'green', 'gold', 'lavender', 'purple']
self.switch = True
self.widgets = []
for i in range(6):
self.widgets.append(tk.Label(self, text=i, bg=colors[i]))
def refresh(self, *args):
self.switch = not self.switch
for w in self.widgets:
w.grid_forget()
positions = [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)]
for i in range(6):
c, r = positions[i][0], positions[i][1]
if self.switch:
c, r = r, c
self.grid_columnconfigure(c, weight=1, uniform="aaa")
self.grid_rowconfigure(r, weight=1, uniform="bbb")
self.widgets[i].grid(column=c, row=r, sticky=tk.NSEW)
def main():
root = tk.Tk()
root.geometry('400x400+20+20')
btn = tk.Button(root, text="click me")
btn.pack(side=tk.TOP, fill=tk.X)
frm = TestGrid(root)
frm.pack(fill=tk.BOTH, expand=1, padx=5, pady=5)
frm.refresh()
btn.bind("<Button-1>", frm.refresh)
root.mainloop()
if __name__ == '__main__':
main()