I am creating a custom tkinter class ResizableLabelFrame() which has a label frame and an inner frame to hold widgets. While resizing the window, the widgets are not getting resized. Could anyone point me in the right direction solving this issue? Thanks in advance.
Most of the time I was able to solve the issues just by reading the questions and answers posted in Stack Overflow and my learning advanced a lot with your help. Thank you so much.
full window
reduced window
I tried columnconfigure(0, weight=1), rowconfigure(0, weight=1) I want to create a custom label frame class which resizes its inner frames and widgets
from tkinter import *
class ResizableLabelFrame(LabelFrame):
def __init__(self, master=None, **kwargs):
LabelFrame.__init__(self, master, **kwargs)
# Set default weight for resizing
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
# Bind the resizing function to the label frame
self.bind("<Configure>", self.on_resize)
# Create a frame inside the LabelFrame to hold widgets
self.inner_frame = Frame(self)
self.inner_frame.grid(row=0, column=0, sticky="nsew")
self.inner_frame.columnconfigure(0, weight=1)
self.inner_frame.rowconfigure(0, weight=1)
resizable_frame_inner_frame_columns = self.inner_frame.grid_size()[0]
print(resizable_frame_inner_frame_columns)
"""
for i in range(resizable_frame_inner_frame_columns):
resizable_frame.columnconfigure(i, weight=1)
"""
def on_resize(self, event):
# Get the new size of the label frame
width = event.width
height = event.height
print(width,"X",height)
# Resize the inner frame to match the label frame's size
self.inner_frame.config(width=width, height=height)
# Resize widgets inside the inner frame if needed
for widget in self.inner_frame.winfo_children():
self.resize_widget(widget)
def resize_widget(self, widget):
# Resize the widget if it has a resize method
if hasattr(widget, "resize"):
widget.resize()
def add_widget(self, widget, position):
# Add a widget to the inner frame
widget.grid(row=0, column=position, padx=10, pady=10, sticky="nsew")
if __name__ == "__main__":
root = Tk()
root.geometry("500x100")
# Create an instance of ResizableLabelFrame
resizable_frame = ResizableLabelFrame(root, text="Controls")
resizable_frame.grid(row=0, column=0, sticky="nsew")
# Add widgets to the resizable frame
label = Label(resizable_frame.inner_frame, text="Enter TOTP")
entry = Entry(resizable_frame.inner_frame)
button = Button(resizable_frame.inner_frame, text="Connect")
resizable_frame.add_widget(label, 0)
resizable_frame.add_widget(entry, 1)
resizable_frame.add_widget(button, 2)
resizable_frame_columns = resizable_frame.grid_size()[0]
print(resizable_frame_columns)
# Example of a widget with a custom resize method
class CustomResizableWidget(Label):
def resize(self):
# Custom resizing logic for the widget
pass
custom_widget = CustomResizableWidget(resizable_frame.inner_frame, text="Connection Status")
resizable_frame.add_widget(custom_widget, 3)
root.mainloop()
It resizes frame when I add
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
or when I remove grid()
and use pack()
resizable_frame.pack(fill='both', expand=True)
Tested on Linux Mint, Python 3.10
To make sure I put full working code after image. And I add comments # <-- HERE
in code.
from tkinter import *
class ResizableLabelFrame(LabelFrame):
def __init__(self, master=None, **kwargs):
LabelFrame.__init__(self, master, **kwargs)
# Set default weight for resizing
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
# Bind the resizing function to the label frame
self.bind("<Configure>", self.on_resize)
# Create a frame inside the LabelFrame to hold widgets
self.inner_frame = Frame(self)
self.inner_frame.grid(row=0, column=0, sticky="nsew")
self.inner_frame.columnconfigure(0, weight=1)
self.inner_frame.rowconfigure(0, weight=1)
resizable_frame_inner_frame_columns = self.inner_frame.grid_size()[0]
print(resizable_frame_inner_frame_columns)
"""
for i in range(resizable_frame_inner_frame_columns):
resizable_frame.columnconfigure(i, weight=1)
"""
def on_resize(self, event):
# Get the new size of the label frame
width = event.width
height = event.height
print(width,"X",height)
# Resize the inner frame to match the label frame's size
self.inner_frame.config(width=width, height=height)
# Resize widgets inside the inner frame if needed
for widget in self.inner_frame.winfo_children():
self.resize_widget(widget)
def resize_widget(self, widget):
# Resize the widget if it has a resize method
if hasattr(widget, "resize"):
widget.resize()
def add_widget(self, widget, position):
# Add a widget to the inner frame
widget.grid(row=0, column=position, padx=10, pady=10, sticky="nsew")
if __name__ == "__main__":
root = Tk()
root.geometry("500x100")
# Create an instance of ResizableLabelFrame
resizable_frame = ResizableLabelFrame(root, text="Controls")
# --- version 1 ---
#resizable_frame.grid(row=0, column=0, sticky="nsew")
#root.columnconfigure(0, weight=1) # <-- HERE
#root.rowconfigure(0, weight=1) # <-- HERE
# --- version 2 ---
resizable_frame.pack(fill='both', expand=True) # <-- HERE
# Add widgets to the resizable frame
label = Label(resizable_frame.inner_frame, text="Enter TOTP")
entry = Entry(resizable_frame.inner_frame)
button = Button(resizable_frame.inner_frame, text="Connect")
resizable_frame.add_widget(label, 0)
resizable_frame.add_widget(entry, 1)
resizable_frame.add_widget(button, 2)
resizable_frame_columns = resizable_frame.grid_size()[0]
print(resizable_frame_columns)
# Example of a widget with a custom resize method
class CustomResizableWidget(Label):
def resize(self):
# Custom resizing logic for the widget
pass
custom_widget = CustomResizableWidget(resizable_frame.inner_frame, text="Connection Status")
resizable_frame.add_widget(custom_widget, 3)
root.mainloop()