I'm building an application that provides viewports for an internal data file. The files are somewhat complex, so I've created three sub-windows that handle different aspects of the file. The upper left provides an outline of the different sections, the upper right provides a series of text widgets containing errors found in the data file, and the lower provides a view of the datafile itself. To facilitate all of this, I wrote a small class that serves as a frame for each of these sections and can be populated with labels, textboxes, etc. (Code below.)
The problem I'm running into is that the text widgets in the upper right and lower sections do not expand with their containing frame. Based on various searches of effbot.org, Stackoverflow, and others, I think I have the settings correct, but obviously something is wrong. If I enlarge the main window, each section adapts as it should, but the text widgets don't expand left to right to fill the new subwindow dimensions.
Any tips are greatly appreciated.
Here's the class that provides functionality for the subwindows:
import Tkinter as tk
class ScrollingChildFrame(tk.Frame):
'''
A Tkinter class creating a scrollable window that can be used
in a docked multiple document interface form. The window created here
allows addition of widgets to create scrolling tables (spreadsheet like),
groups of text fields, etc.
'''
def __init__(self, root):
self.count = 0
tk.Frame.__init__(self)
self.root = root
self.canvas = tk.Canvas(self, height=self.winfo_height(), width=self.winfo_width() )
self.canvas.grid(row=0, column=0, sticky='nsew')
self.vsb = tk.Scrollbar(self, orient='vertical', command=self.canvas.yview)
self.vsb.grid(row=0,column=1,sticky='ns')
self.hsb = tk.Scrollbar(self, orient='horizontal', command=self.canvas.xview)
self.hsb.grid(row=1,column=0,sticky='ew')
self.intframe = tk.Frame(self.canvas)
self.intframe.config(height=self.winfo_height(), width=self.winfo_width())
self.canvas.configure(yscrollcommand=self.vsb.set, xscrollcommand=self.hsb.set)
self.canvas.create_window(0, 0, window=self.intframe, anchor='nw')
#set event bindings
self.bind('<Configure>', self.OnFrameConfigure)
self.intframe.bind('<Configure>', self.OnIntFrameConfigure)
def OnFrameConfigure(self, event=None):
'''
adjust canvas when main frame adjusts
'''
self.canvas.configure(width=event.width - self.vsb.winfo_width()-2,
height=event.height - self.hsb.winfo_height()-2)
def OnIntFrameConfigure(self, event=None):
'''
adjust the scrolling window when the internal frame is adjusted
'''
self.canvas.configure(scrollregion=self.canvas.bbox(tk.ALL))
Here's an example of how I'm using it with textboxes that don't expand:
import Tkinter as tk
from scrollingchildframe import *
class Vis_GUI:
'''
The main GUI class
'''
def __init__(self):
#tkinter stuff
self.root = tk.Tk()
self.root.geometry('500x500')
self.create_frames()
self.root.mainloop()
def create_frames(self):
'''
Build the GUI frames
'''
self.root.columnconfigure(0,weight=1)
self.root.columnconfigure(1,weight=3)
self.root.rowconfigure(0,weight=1)
self.root.rowconfigure(1,weight=3)
#data blocks
self.block_frame = ScrollingChildFrame(self.root)
self.block_frame.config(height=200, width=200)
##error list
self.error_frame = ScrollingChildFrame(self.root)
self.error_frame.config(height=200, width=300)
##data
self.data_frame = ScrollingChildFrame(self.root)
self.data_frame.config(height=300, width=500)
##populate with empty cells
self.PopulateEmpty()
##place them on the grid
self.block_frame.grid(row=0, column=0, padx=2, pady=2, sticky='nsew')
self.error_frame.grid(row=0,column=1, padx=2, pady=2, sticky='nsew')
self.data_frame.grid(row=1, column=0, columnspan=2, padx=2,pady=2, sticky='nsew')
def PopulateEmpty(self):
'''
Populate the frames with empty contents so it doesn't look quite so empty.
'''
z = tk.Text(self.data_frame.intframe)
z.insert(tk.INSERT, 'blah\nblah\nblah')
height = float(z.index(tk.END))
z.config( height=height, state=tk.DISABLED, wrap=tk.NONE)
z.pack(anchor='nw', expand=1, fill=tk.X)
z = tk.Text(self.error_frame.intframe, height=1)
z.pack(anchor='w', expand = 1, fill=tk.X)
z = tk.Label(self.block_frame.intframe, text = 'No file open')
z.pack(anchor='w')
if (__name__=="__main__"):
wv = Vis_GUI()