The following code creates a canvas with a frame inside. I am using the canvas to enable the addition of a vertical scrollbar, which appears as necessary. I have coloured the various sections - root, blue; window, green; canvas, red and frame, cyan. From this it can be seen that window completely fills root (no blue seen). However, canvas only fills window in the vertical direction (green visible to the rhs on expanding the window, and frame only fills canvas in the horizontal direction (red visible below cyan). I can't see what is causing the problem. Frame is bound to canvas and canvas has sticky='nsew' set so should be filling window.
import Tkinter as tk
import tkFileDialog
class AutoScrollbar(tk.Scrollbar):
# a scrollbar that hides itself if it's not needed. only
# works if you use the grid geometry manager.
def set(self, lo, hi):
if float(lo) <= 0.0 and float(hi) >= 1.0:
# grid_remove is currently missing from Tkinter!
self.tk.call("grid", "remove", self)
else:
self.grid()
tk.Scrollbar.set(self, lo, hi)
def pack(self, **kw):
raise TclError, "cannot use pack with this widget"
def place(self, **kw):
raise TclError, "cannot use place with this widget"
class Window(tk.Frame):
def UserInput(self,status,name):
row = self.row
optionLabel = tk.Label(self.frame)
optionLabel["text"] = name
optionLabel.grid(row=row, column=0, sticky='w')
var = tk.StringVar(root)
var.set(status)
w = tk.Entry(self.frame, textvariable= var)
w.grid(row=row, column=1, sticky='ew')
self.grid_columnconfigure(1,weight=1)
self.row += 1
return w
def on_canvas_resize(self,event):
padding = 8
width = self.canvas.winfo_width() - padding
self.canvas.itemconfigure("frame", width=width)
def OnFrameConfigure(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def __init__(self,parent):
tk.Frame.__init__(self,parent)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0,weight=1)
self.vscrollbar = AutoScrollbar(self,orient = tk.VERTICAL)
self.vscrollbar.grid(row = 0,column = 3, sticky = 'ns')
self.canvas = tk.Canvas(self, yscrollcommand = self.vscrollbar.set,bg='red')
self.canvas.grid(row=0, column=0, sticky='nsew')
self.canvas.grid_rowconfigure(0, weight = 1)
self.canvas.grid_columnconfigure(0, weight = 1)
self.frame = tk.Frame(self.canvas, bg='cyan')
self.frame.bind("<Configure>", self.OnFrameConfigure)
self.frame.grid_rowconfigure(0, weight=1)
self.frame.grid_columnconfigure(0,weight=1)
self.frame.grid_columnconfigure(1,weight=3)
self.vscrollbar.config(command=self.canvas.yview)
self.canvas.create_window(0, 0, anchor = tk.NW, window= self.frame, tags =["frame"])
self.canvas.bind("<Configure>", self.on_canvas_resize)
self.row = 0
for i in range(10):
self.Number = self.UserInput("1", "number")
if __name__ == "__main__":
root = tk.Tk()
root.configure(background='blue')
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0,weight=1)
window = Window(root)
window.configure(background='green')
window.grid(row=0,column=0,sticky='nsew')
root.mainloop()