Fill frame on window resize - python

When you enter a file name in the entry filed and click the "Open" button, the content will be displayed.
I want the Entry and Text widget to completely fill Frame3 (red) and continue to do so when the application window is resized. How do I achieve this?
This is my code:
from Tkinter import *
ALL = N+S+W+E
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.rowconfigure(0, weight=1)
self.master.columnconfigure(0, weight=1)
self.grid(sticky=ALL)
def handler(event):
print("clicked at", event.x, event.y)
def show_entry_fields():
#print e1.get()
f=open(e1.get())
out_put=f.read()
l1=Label(f3, text=out_put,fg="purple").grid(row=5,column=2)
return out_put
def call_red():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="red").grid(row=5,column=2)
def call_green():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="green").grid(row=5,column=2)
def call_blue():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="blue").grid(row=5,column=2)
def call_black():
out_put=show_entry_fields()
Label(f3, text=out_put,fg="black").grid(row=5,column=2)
for r in range(4):
self.rowconfigure(r, weight=1)
self.master.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
b1=Button(self, text="Red",command=call_red).grid(row=5, column=0, sticky=ALL)
self.columnconfigure(1, weight=1)
b2=Button(self, text="Blue",command=call_blue).grid(row=5, column=1, sticky=ALL)
self.columnconfigure(2, weight=1)
b3=Button(self, text="Green",command=call_green).grid(row=5, column=2, sticky=ALL)
self.columnconfigure(3, weight=1)
b4=Button(self, text="Black",command=call_black ).grid(row=5, column=3, sticky=ALL)
self.columnconfigure(4, weight=1)
b5=Button(self, text="Open",command=show_entry_fields).grid(row=5, column=4, sticky=ALL)
#------------------------------
f1 = Frame(self, bg="blue")
f1.grid(row=0, column=0, rowspan=2,columnspan=2, sticky=ALL)
f1.bind("<Button-1>", handler)
f1.focus()
f2 = Frame(self, bg="green")
f2.grid(row=2, column=0, rowspan=2,columnspan=2, sticky=ALL)
f2.bind("<Button-1>", handler)
f2.focus()
f3 = Frame(self, bg="red")
f3.grid(row=0, column=2, rowspan=4, columnspan=4, sticky=ALL)
l=Label(f3, text="Enter File Path:").grid(row=1)
e1 = Entry(f3)
e1.grid(row=1,column=2)
root = Tk()
app = Application(master=root)
app.mainloop()

You should assign a weight to the column and row in which you place the text:
f3.grid_columnconfigure(2, weight=1)
f3.grid_rowconfigure(5, weight=1)
This tells Tkinter that it should distribute any extra space to that row and column, which will make the cell grow upon resize.
You might want to add sticky=ALL to your e1 then too, so it resizes with the text below it.

Related

TKInter frame losing grid layout when insert scrollbar

I'm trying to create an app with a frame with two frames inside, but I want one of then to be wider than the other... I found a way to do it using grid, but when I add a scrollbar on one of the frames it readjusts the grid and both frames get the same size.
Here is the code working without the scrollbar:
def __init__(self, master=None):
ctk.set_appearance_mode('system')
ctk.set_default_color_theme('blue')
self.__root = ctk.CTk() if master is None else ctk.CTkToplevel(master)
self.__root. Configure(height=1500, width=944)
self.__root.minsize(1500, 944)
self.__main_container = ctk.CTkFrame(self.__root)
self.__image_frame = ctk.CTkFrame(self.__main_container)
self.__image_frame.configure(height=800, width=1000)
self.__image_canvas = ctk.CTkCanvas(self.__image_frame)
self.__image_canvas.configure(confine="true", cursor="crosshair")
self.__image_canvas.grid(column=0, row=0, sticky="nsew")
self.__image_canvas.bind("<ButtonPress-1>", self.__start_drawing)
self.__image_canvas.bind("<ButtonRelease-1>", self.__end_drawing)
self.__image_canvas.bind("<B1-Motion>", self.__draw_rectangle)
self.__image_frame.grid(column=0, padx=10, pady=20, row=0, sticky="nsew")
self.__image_frame.grid_propagate(0)
self.__image_frame.grid_anchor("center")
self.__image_frame.rowconfigure(0, weight=1)
self.__image_frame.columnconfigure(0, weight=1)
self.__boxes_frame = ctk.CTkFrame(self.__main_container)
self.__boxes_frame.configure(height=800, width=400)
self.__boxes_frame.grid(column=1, padx=10, pady=20, row=0, sticky="ns")
self.__main_container.grid(column=0, padx=20, pady=40, row=0, sticky="ns")
self.__main_container.grid_anchor("center")
self.__main_container.rowconfigure(0, weight=1)
self.__root.grid_anchor("center")
self.__root.rowconfigure(0, weight=1)
self.mainwindow = self.__root
And this is the code when I add the scrollbar and messes the grid
def __init__(self, master=None):
ctk.set_appearance_mode('system')
ctk.set_default_color_theme('blue')
self.__root = ctk.CTk() if master is None else ctk.CTkToplevel(master)
self.__root. Configure(height=1500, width=944)
self.__root.minsize(1500, 944)
self.__main_container = ctk.CTkFrame(self.__root)
self.__image_frame = ctk.CTkFrame(self.__main_container)
self.__image_frame.configure(height=800, width=1000)
self.__image_canvas = ctk.CTkCanvas(self.__image_frame)
self.__image_canvas.configure(confine="true", cursor="crosshair")
self.__image_canvas.grid(column=0, row=0, sticky="nsew")
self.__image_canvas.bind("<ButtonPress-1>", self.__start_drawing)
self.__image_canvas.bind("<ButtonRelease-1>", self.__end_drawing)
self.__image_canvas.bind("<B1-Motion>", self.__draw_rectangle)
#------ adding the scrollbar -----
self.__image_frame_vertical_scrollbar = ctk.CTkScrollbar(self.__image_frame, orientation="vertical")
self.__image_frame_vertical_scrollbar.grid(column=1, row=0, sticky="ns")
self.__image_frame_vertical_scrollbar.configure(command=self.__image_canvas.yview)
self.__image_canvas.configure(yscrollcommand=self.__image_frame_vertical_scrollbar.set)
#---------------------------------
self.__image_frame.grid(column=0, padx=10, pady=20, row=0, sticky="nsew")
self.__image_frame.grid_propagate(0)
self.__image_frame.grid_anchor("center")
self.__image_frame.rowconfigure(0, weight=1)
self.__image_frame.columnconfigure(0, weight=1)
self.__boxes_frame = ctk.CTkFrame(self.__main_container)
self.__boxes_frame.configure(height=800, width=400)
self.__boxes_frame.grid(column=1, padx=10, pady=20, row=0, sticky="ns")
self.__main_container.grid(column=0, padx=20, pady=40, row=0, sticky="ns")
self.__main_container.grid_anchor("center")
self.__main_container.rowconfigure(0, weight=1)
self.__root.grid_anchor("center")
self.__root.rowconfigure(0, weight=1)
self.mainwindow = self.__root
What is wrong with the grid definition that is messing things up? How can I set the __image_frame grid to it fills the __main_container keeping the desired dimensions?
Set the size of the canvas explicitly
self.__image_canvas = ctk.CTkCanvas(self.__image_frame, width=900)

Tkinter grid doesn't expand when the windows change its size

I'm new using Tkinter, I already have this problem, I was thinking the problem was the column and row configure, but that doesn't change anything.
This is what I get:
This is my code:
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.grid()
self.grid_rowconfigure(0, weight=1)
self.grid_rowconfigure(1, weight=1)
self.grid_rowconfigure(2, weight=1)
self.grid_rowconfigure(3, weight=1)
self.grid_rowconfigure(4, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
self.create_widgets()
def create_widgets(self):
self.label = Label(self, justify=LEFT)
self.label["text"] = "NĂºmero:"
self.label.grid(column=0, row=0, sticky="e")
self.input = Entry(self)
self.input.grid(column=1, row=0, sticky="we")
self.baseValue = StringVar()
self.baseValue.set(basesNames[0]) # default value
self.label2 = Label(self)
self.label2["text"] = "Base:"
self.label2.grid(column=0, row=1, sticky="e")
self.menuNumber = ttk.Combobox(self, textvariable=self.baseValue)
self.menuNumber['values'] = basesNames
self.menuNumber.grid(column=1, row=1)
self.label2 = Label(self)
self.label2["text"] = "Base de resultado: "
self.label2.grid(column=0, row=2, sticky="e")
self.baseValueResult = StringVar()
self.baseValueResult.set(basesNames[0]) # default value
self.menuNumberResult = ttk.Combobox(self, textvariable=self.baseValueResult)
self.menuNumberResult['values'] = basesNames
self.menuNumberResult.grid(column=1, row=2)
self.convert = ttk.Button(self, text="Convertir", command=self.convertNumber)
self.convert.grid(row = 4, columnspan=2, sticky="sn")
self.result = Label(self)
self.result["text"] = "Your result is: "
self.result.grid(row=3, columnspan=2, sticky="ew")
root = Tk()
app = Application(master=root)
app.master.title("Conversor de bases")
app.master.maxsize(1000, 400)
app.mainloop()
Also, I checked if the sticky param was necessary but that doesn't change neither
Your widgets are wrapped inside the frame Application. So you need to make the frame expands as well.
from tkinter import *
from tkinter import ttk
basesNames = ["a","b","c","d","e"]
class Application(Frame):
def __init__(self, master=None):
...
root = Tk()
app = Application(master=root)
app.master.title("Conversor de bases")
app.master.maxsize(1000, 400)
root.rowconfigure(0,weight=1)
root.columnconfigure(0,weight=1)
root.mainloop()

Python tkinter widgets get resized uneven when user resizes the window

I am using a template that I saw in a youtube video for my app. I have split the window in 3 using 3 frames. All 3 frames are nested into a main frame. The main frame is attached directly to the root window.
I am using pack manager in order to place mainframe inside the root window.
I am using grid manager in order to place the 3 frames inside the mainframe.
The issue that I'm facing is that when I try to resize the window the left frame gets resized more than the other 2 frames, and I don't understand why that happens. I need the frames to resize proportionately to each other. Why is the left frame getting resized more than the others? and how can I correct this?
import tkinter as tk
from tkinter import ttk
Normal_Font = ('Verdana', 9)
Large_font = ('Verdana', 12)
class MainApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
mainframe = tk.Frame(self)
mainframe.pack(side='top', fill='both', expand=True)
mainframe.grid_rowconfigure(0, weight=1)
mainframe.grid_columnconfigure(0, weight=1)
#mainframe.grid(row=0, column=0, sticky='nesw')
#left frame
employerframe = tk.Frame(mainframe)
employerframe.grid(row=0, column=0, sticky='nesw')
employerframe.grid_rowconfigure(0, weight=1)
employerframe.grid_columnconfigure(0, weight=1, uniform=1)
label1 = tk.Label(employerframe, text='Employer Frame', font=Large_font)
label1.grid(row=0, column=0, sticky='nesw')
ttk.Separator(mainframe, orient=tk.VERTICAL) .grid(row=0, column=1, sticky='ns')
#right frame
candidateframe = tk.Frame(mainframe)
candidateframe.grid(row=0, column=4, sticky='nesw')
candidateframe.grid_rowconfigure(0, weight=1)
candidateframe.grid_columnconfigure(0, weight=1, uniform=1)
label2 = tk.Label(candidateframe, text='Candidate Frame', font=Large_font)
label2.grid(row=0, column=0, sticky='nesw')
ttk.Separator(mainframe, orient=tk.VERTICAL) .grid(row=0, column=3, sticky='ns')
#middle frame
container = tk.Frame(mainframe)
container.grid(row=0, column=2, sticky='nesw')
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1, uniform=1)
self.frames = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky='nesw')
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Start Page', font=Large_font)
label.pack(pady=10, padx=10)
app = MainApp()
app.mainloop()
It's because you are placing employerframe, container, candidateframe to column=0, column=2, column=4. But giving weight=1 to only column=0. you have to add the following lines also to give column, 0, 2, 4 equal weight.
mainframe.grid_columnconfigure(2, weight=1)
mainframe.grid_columnconfigure(4, weight=1)
Try This:
import tkinter as tk
from tkinter import ttk
Normal_Font = ('Verdana', 9)
Large_font = ('Verdana', 12)
class MainApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
mainframe = tk.Frame(self)
mainframe.pack(side='top', fill='both', expand=True)
mainframe.grid_rowconfigure(0, weight=1)
mainframe.grid_columnconfigure(0, weight=1)
# ----- Added lines -----
mainframe.grid_columnconfigure(2, weight=1)
mainframe.grid_columnconfigure(4, weight=1)
#left frame
employerframe = tk.Frame(mainframe)
employerframe.grid(row=0, column=0, sticky='nesw')
label1 = tk.Label(employerframe, text='Employer Frame', font=Large_font)
label1.grid(row=0, column=0, sticky='nesw')
ttk.Separator(mainframe, orient=tk.VERTICAL) .grid(row=0, column=1, sticky='ns')
#right frame
candidateframe = tk.Frame(mainframe)
candidateframe.grid(row=0, column=4, sticky='nesw')
label2 = tk.Label(candidateframe, text='Candidate Frame', font=Large_font)
label2.grid(row=0, column=0, sticky='nesw')
ttk.Separator(mainframe, orient=tk.VERTICAL) .grid(row=0, column=3, sticky='ns')
#middle frame
container = tk.Frame(mainframe)
container.grid(row=0, column=2, sticky='nesw')
self.frames = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky='nesw')
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Start Page', font=Large_font)
label.pack(pady=10, padx=10)
app = MainApp()
app.mainloop()

extra spaces between buttons in tkinter

I have implemented a code to make GUI using Tkinter and I'm new in this. The problem which I'm facing is that there is lots of spacing between two buttons in column 3 ( select object and play button).
I want to know that why this is happening.
my code is here:
from tkinter import Tk, Text, BOTH, W, N, E, S
from tkinter.ttk import Frame, Button, Label, Style
class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Nav Track app")
self.pack(fill=BOTH, expand=True)
self.style = Style()
self.style.theme_use("default")
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
lbl = Label(self, text="Keep your eyes on screen")
lbl.grid(sticky=W, pady=4, padx=5)
area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=5,
padx=8, sticky=E + W + S + N)
abtn = Button(self, text="Start Camera")
abtn.grid(row=1, column=3, padx=4)
cbtn = Button(self, text="Select Object")
cbtn.grid(row=2, column=3, padx=4, pady=4)
dbtn = Button(self, text="Play")
dbtn.grid(row=3, column=3, padx=4, pady=4)
hbtn = Button(self, text="Help")
hbtn.grid(row=7, column=0, padx=5)
obtn = Button(self, text="Exit")
obtn.grid(row=7, column=3)
def main():
root = Tk()
root.geometry("500x450+300+500")
app = Example()
root.mainloop()
if __name__ == '__main__':
main()

Python Tkinter: Paned Window not sticking to top

Thanks for taking time to look at this. I've been struggling with this for almost a week and its driving me crazy.
I have a horizontal Paned Window which is supposed to stretch from the bottom of my toolbar to the bottom of my window, but it's sticking only to the bottom of the root window. Eventually I want to have a Treeview widget in the left pane and thumbnails in the right pane.
Can anyone help me to get the Paned Window to stick NSEW? Do I need to put it inside another frame?
I'm using Python 2.7 on Windows 7. (This isn't my whole program, just a sample to demonstrate the problem.)
#!/usr/bin/env python
# coding=utf-8
from Tkinter import *
from ttk import *
class MainWindow:
def null(self):
pass
def __init__(self):
self.root = Tk()
self.root.geometry("700x300")
self.root.resizable(width=TRUE, height=TRUE)
self.root.rowconfigure(0, weight=1)
self.root.columnconfigure(0, weight=1)
self.menubar = Menu(self.root)
File_menu = Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="Pandoras Box", menu=File_menu)
File_menu.add_command(label="Black Hole", command=self.null)
self.root.config(menu=self.menubar)
self.toolbar = Frame(self.root, relief=RAISED)
self.toolbar.grid(row=0, column=0, sticky='NEW')
self.toolbar.grid_columnconfigure(0, weight=1)
self.toolbar.rowconfigure(0, weight=1)
dummy = Button(self.toolbar, text="Tool Button")
dummy.grid(row=0, column=0, sticky='EW')
Find = Label(self.toolbar, text="Search")
Search = Entry(self.toolbar)
Find.grid(row=0, column=5, sticky='E', padx=6)
Search.grid(row=0, column=6, sticky='E', padx=8)
self.info_column = Frame(self.root, relief=RAISED, width=100)
self.info_column.grid(row=0, column=5, rowspan=3, sticky='NSW')
self.info_column.grid_rowconfigure(0, weight=1)
self.info_column.grid_columnconfigure(0, weight=1)
self.rootpane = PanedWindow(self.root, orient=HORIZONTAL)
self.rootpane.grid(row=1, column=0, sticky='NS')
self.rootpane.grid_rowconfigure(0, weight=1)
self.rootpane.grid_columnconfigure(0, weight=1)
self.leftpane = Frame(self.rootpane, relief=RAISED)
self.leftpane.grid(row=0, column=0, sticky='NSEW')
self.rightpane = Frame(self.rootpane, relief=RAISED)
self.rightpane.grid(row=0, column=0, sticky='NSEW')
''' THESE BUTTONS ARE SUPPOSED TO BE INSIDE PANED WINDOW STUCK TO THE TOP!'''
but_left = Button(self.leftpane, text="SHOULD BE IN LEFT PANE UNDER TOOLBAR FRAME")
but_left.grid(row=0, column=0, sticky='NEW')
but_right = Button(self.rightpane, text="SHOULD BE IN RIGHT PANE UNDER TOOLBAR FRAME")
but_right.grid(row=0, column=0, sticky='NEW')
self.rootpane.add(self.leftpane)
self.rootpane.add(self.rightpane)
self.SbarMesg = StringVar()
self.label = Label(self.root, textvariable=self.SbarMesg, font=('arial', 8, 'normal'))
self.SbarMesg.set('Status Bar:')
self.label.grid(row=3, column=0, columnspan=6, sticky='SEW')
self.label.grid_rowconfigure(0, weight=1)
self.label.grid_columnconfigure(0, weight=1)
self.root.mainloop()
a = MainWindow()
Short answer: the space you see between the buttons and the toolbar frame is because you allow the row containing the toolbar to resize, instead of the row containing the PanedWindow... To get what you want, replace:
self.root.rowconfigure(0, weight=1)
with
self.root.rowconfigure(1, weight=1)
Other comments:
Try to avoid wildcard imports. In this case, it makes it difficult to differentiate between tk and ttk widgets
To allow resizing of widgets aligned using grid(), .rowconfigure(..., weight=x) must be called on the widget's parent not the widget itself.
background colors are very useful to debug alignment issues in tkinter.
Code:
import Tkinter as tk
import ttk
class MainWindow:
def __init__(self):
self.root = tk.Tk()
self.root.geometry("700x300")
self.root.resizable(width=tk.TRUE, height=tk.TRUE)
self.root.rowconfigure(1, weight=1)
self.root.columnconfigure(0, weight=1)
self.toolbar = tk.Frame(self.root, relief=tk.RAISED, bg="yellow")
self.toolbar.grid(row=0, column=0, sticky='NEW')
self.toolbar.columnconfigure(0, weight=1)
dummy = ttk.Button(self.toolbar, text="Tool Button")
dummy.grid(row=0, column=0, sticky='EW')
Find = tk.Label(self.toolbar, text="Search")
Search = ttk.Entry(self.toolbar)
Find.grid(row=0, column=5, sticky='E', padx=6)
Search.grid(row=0, column=6, sticky='E', padx=8)
self.info_column = tk.Frame(self.root, relief=tk.RAISED, width=100, bg="orange")
self.info_column.grid(row=0, column=5, rowspan=2, sticky='NSW')
self.rootpane = tk.PanedWindow(self.root, orient=tk.HORIZONTAL, bg="blue")
self.rootpane.grid(row=1, column=0, sticky='NSEW')
self.leftpane = tk.Frame(self.rootpane, bg="pink")
self.rootpane.add(self.leftpane)
self.rightpane = tk.Frame(self.rootpane, bg="red")
self.rootpane.add(self.rightpane)
''' THESE BUTTONS ARE SUPPOSED TO BE INSIDE PANED WINDOW STUCK TO THE TOP!'''
but_left = ttk.Button(self.leftpane, text="SHOULD BE IN LEFT PANE UNDER TOOLBAR FRAME")
but_left.grid(row=0, column=0, sticky='NEW')
but_right = ttk.Button(self.rightpane, text="SHOULD BE IN RIGHT PANE UNDER TOOLBAR FRAME")
but_right.grid(row=0, column=0, sticky='NEW')
self.label = tk.Label(self.root, text="Status:", anchor="w")
self.label.grid(row=3, column=0, columnspan=6, sticky='SEW')
self.root.mainloop()
a = MainWindow()

Categories

Resources