Reputation: 651
I'm creating a GUI in Tkinter. I've tried over and over trying to get my widgets stretch with my GUI. I'm using the sticky commands and col/row weights. On the design viewer tab, I want the Listbox to stretch vertically with the window and I want the Canvas with the blue box to stretch Vertically and Horizontally. I added an image for clarification of what I would expect to happen.
Thanks in advance! Here is my code:
# Gui
import tkinter as tk
from tkinter import N,W,S,E
from tkinter import messagebox
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.grid(sticky = N+E+S+W)
self.create_application_foundation()
def create_application_foundation(self):
# Create menubar ribbon
self.topRibbon = tk.Frame(self, bg = "#E3E5E6")
self.topRibbon.grid(row=0, column=0, sticky=W+E+N+S)
# Initialize Buttons
width = 15; height = 2; bg = "#F5F6F7"; relief = "flat"; bd = 0; padx = 1
self.designViewerButton = tk.Button(self.topRibbon, text = "Design\nViewer", width = width,
height = height, bg = bg, relief = relief, bd = bd)
self.patternCreatorButton = tk.Button(self.topRibbon, text = "Pattern\nCreator",width = width,
height = height, bg = bg, relief = relief, bd = bd)
# Add buttons to ribbon
self.designViewerButton.grid(row = 1, column = 0, padx = padx, sticky = N+W)
self.patternCreatorButton.grid(row = 1, column = 1, padx = padx, sticky = N+W)
# Create design viewer window
self.createdesignViewerWindow()
self.createObjectCreator()
# Try to make things expandable
self.topRibbon.grid_rowconfigure(1, weight=1)
self.topRibbon.grid_columnconfigure(1, weight=1)
def createdesignViewerWindow(self):
width = 30; height = 1; bg = "#F5F6F7"; relief = "flat"; bd = 0; pady = 1
# Create window
self.designViewerWindow = tk.Frame(self, bg = "#E3E5E6")
self.designViewerWindow.grid(row=1, column=0, sticky =W+E+N+S)
# Create object button
self.objectButton = tk.Button(self.designViewerWindow, text = "Object", width = width,
height = height, bg = bg, relief = relief, bd = bd)
self.objectButton.grid(row = 0, sticky =N+W, pady = pady)
# Create object listbox
self.objectListBox = tk.Listbox(self.designViewerWindow)
objects = ["Object {}".format(i) for i in range(50)]
self.objectListBoxFrame = tk.Frame(self.designViewerWindow)
self.objectsListBox = tk.Canvas(self.objectListBoxFrame, width=100, height=200)
self.objectsListBox.grid(row = 0, rowspan = 5,column = 0, sticky = N+S)
self.objectListBoxFrame.grid(row = 1, sticky = N+S, pady = pady)
# Create canvas with blue rectangle
self.imageCanvas = tk.Canvas(self.designViewerWindow, width=200, height=100)
self.imageCanvas.grid(row = 0, rowspan = 5,column = 1, columnspan = 5, sticky = N+E+S+W)
self.imageCanvas.create_rectangle(50, 25, 150, 75, fill="blue")
self.imageCanvas.config(bg = "white")
# Attempt to make window expandable
self.designViewerWindow.rowconfigure(1,weight = 1)
self.designViewerWindow.columnconfigure(1, weight=1)
def createObjectCreator(self):
self.objectCreatorWindow = tk.Frame(self,bg = "#E3E5E6")
self.tempLabel = tk.Label(self.objectCreatorWindow, text = "Object Creator").grid()
if __name__ == "__main__":
import sys
root = tk.Tk()
root.title("My Program")
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(1, weight=1)
# root.minsize(400,200)
app = Application(master=root)
app.mainloop()
Upvotes: 1
Views: 1198
Reputation: 385800
The first part of the problem is that you haven't configured the app to fill the window, so anything inside the app won't fill the window.
You seem to be attempting to, but you're giving all of the weight in the root window to row and column 1, but you're putting app
in row and column 0. You need to give the weight to row and column 0:
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
Note: if you only have one widget in a container, it's easier to use pack since you can configure it to fill the window with just one line of code rather than three.
For example:
self.pack(fill="both", expand=True)
... versus
self.grid(sticky = N+E+S+W)
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
The next problem is that you're putting widgets in the Application
frame with grid
, but you haven't given weight to any rows or columns in the Application
frame. So once again, this frame won't fill its parent so any widget inside won't fill the window either.
I think you want column 0 to get all of the extra space, but you want row 1 to be the row that gets the extra space since that's where self.designViewerWindow
is.
Add the following to the __init__
of Application
:
class Application(tk.Frame):
def __init__(self, master=None):
...
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(0, weight=1)
...
There are other problems, but this shows the general problem: you aren't properly configuring the rows and columns for each group of widgets. As a rule of thumb, for every widget that has children managed by grid
you need to give a positive weight to at least one row and one column.
This would all be a bit easier to see if you grouped together all of the calls to grid
for children of the same widget, and then added the rowconfigure
and columnconfigure
commands in the same place. That way you can easily see all of the grid options for each group at a glance.
Upvotes: 2