Welcome, guest | Sign In | My Account | Store | Cart
from Tkinter import *

class PannedGrid(Frame):
	def __init__(self, master, tableOfWidgets,  minsize='auto', columnWidthList= None, fixedColumns=[]):
		Frame.__init__(self,master)

		self.numberOfRows = len(tableOfWidgets)
		self.numberOfColumns = len(tableOfWidgets[0])
		self.rowHeightList = [0]*self.numberOfRows
		
		self.columnWidthList = [0]*self.numberOfColumns

		self.listOfColumnsFrames = []

		self.gridOfCellWidgets = \
			[[None for j in range(self.numberOfColumns)] for i in range(self.numberOfRows)]


		typeOfColumn = 'fixed'
		
		for j in range(self.numberOfColumns):
			if j in fixedColumns:
				masterFrame = Frame(self)
				typeOfColumn = 'fixed'
			elif typeOfColumn == 'fixed':
				masterFrame = PanedWindow(self,orient=HORIZONTAL   )
				typeOfColumn = 'mobile'
			
			masterFrame.pack(side=LEFT)
			
			columnFrame = Frame(masterFrame)
			columnFrame.pack()
			columnFrame.pack_propagate(False)
			
			if typeOfColumn == 'mobile':
				masterFrame.add(columnFrame)

			self.listOfColumnsFrames.append((typeOfColumn,masterFrame,columnFrame))
			
			for i in range(self.numberOfRows):
				cellFrame = Frame(columnFrame, bd=1, relief=SUNKEN)
				cellFrame.pack(expand=YES, fill=X)
				cellFrame.pack_propagate(False)
				
				widgetDefinition = tableOfWidgets[i][j]

				classObject, kwargs = widgetDefinition

				widget = classObject(cellFrame, **kwargs)
				widget.pack(expand=YES, fill=BOTH)

				self.rowHeightList[i] = max(self.rowHeightList[i],widget.winfo_reqheight())
				
				self.columnWidthList[j] = max(self.columnWidthList[j],widget.winfo_reqwidth())

				self.gridOfCellWidgets[i][j]= cellFrame


		tableHeight = sum(self.rowHeightList)


		for indexColumn, (typeOfColumn,masterFrame,columnFrame) in enumerate(self.listOfColumnsFrames):
			if columnWidthList:
				if columnWidthList[indexColumn] == 'auto':
					columnWidth = self.columnWidthList[indexColumn]
				else:
					columnWidth = columnWidthList[indexColumn]
			else:
				columnWidth = self.columnWidthList[indexColumn]
			
			columnFrame.configure(width=columnWidth, height=tableHeight)
			
			if typeOfColumn == 'mobile':
				if minsize == 'auto':
					masterFrame.paneconfigure(columnFrame, minsize=self.columnWidthList[indexColumn])
				elif type(minsize) is int:
					masterFrame.paneconfigure(columnFrame, minsize=minsize)
				else:
					raise Exception("Minsize must be 'auto' or an integer.")

		
		for i in range(self.numberOfRows):
			for j in range(self.numberOfColumns):
				self.gridOfCellWidgets[i][j].configure(height=self.rowHeightList[i])


def test():
	import random

	root = Tk()

	def build_random_table(master, numRows,numColumns, minsize, fixedColumns, columnWidthList = None):
		import ttk
		
		tkinterWidgets =  (
					(Label, {'text':'This is a label'}), 
					(Label, {'text':'This is another label', 'bg':'yellow'}),
					(Checkbutton,{}),
					(Button, {'text':'Click me'}),
					(ttk.Combobox, {'values':('item1', 'item2','item3','item4')})
					)
		tableGrid = []


		for i in range(numRows):
			row = [random.choice(tkinterWidgets) for j in range(numColumns) ]

			tableGrid.append(row)

		PannedGrid(master, tableGrid,minsize=minsize,fixedColumns=fixedColumns, columnWidthList=columnWidthList).pack(anchor=NW,pady=2, padx='2m')

	Label(root, text="minsize = 20, fixed columns = [2,5]").pack(anchor=NW, pady=6, padx='2m') 
	build_random_table(root, numRows=4,numColumns=6, minsize=20, fixedColumns=[2,5])	

	emptySpace = Frame(root, height =30)
	emptySpace.pack()
	
	Label(root, text="minsize = auto, fixed columns = [2,5], columnWidthList=[200, 'auto', 200, 'auto', 250, 'auto']").pack(anchor=NW, pady=6, padx='2m') 
	build_random_table(root, numRows=4,numColumns=6, minsize='auto', columnWidthList=[200, 'auto', 200, 'auto', 250, 'auto'], fixedColumns=[2,5])
	
	root.mainloop()



if __name__ == '__main__':
	test()

Diff to Previous Revision

--- revision 3 2014-05-03 21:22:12
+++ revision 4 2014-05-07 15:52:22
@@ -1,13 +1,14 @@
 from Tkinter import *
 
 class PannedGrid(Frame):
-	def __init__(self, master, tableOfWidgets, minsize='auto', fixedColumns=[]):
+	def __init__(self, master, tableOfWidgets,  minsize='auto', columnWidthList= None, fixedColumns=[]):
 		Frame.__init__(self,master)
 
 		self.numberOfRows = len(tableOfWidgets)
 		self.numberOfColumns = len(tableOfWidgets[0])
-		RowHeightList = [0]*self.numberOfRows
-		ColumnWidthList = [0]*self.numberOfColumns
+		self.rowHeightList = [0]*self.numberOfRows
+		
+		self.columnWidthList = [0]*self.numberOfColumns
 
 		self.listOfColumnsFrames = []
 
@@ -48,22 +49,30 @@
 				widget = classObject(cellFrame, **kwargs)
 				widget.pack(expand=YES, fill=BOTH)
 
-				RowHeightList[i] = max(RowHeightList[i],widget.winfo_reqheight())
-				ColumnWidthList[j] = max(ColumnWidthList[j],widget.winfo_reqwidth())
+				self.rowHeightList[i] = max(self.rowHeightList[i],widget.winfo_reqheight())
+				
+				self.columnWidthList[j] = max(self.columnWidthList[j],widget.winfo_reqwidth())
 
 				self.gridOfCellWidgets[i][j]= cellFrame
 
 
-		tableHeight = sum(RowHeightList)
+		tableHeight = sum(self.rowHeightList)
 
 
 		for indexColumn, (typeOfColumn,masterFrame,columnFrame) in enumerate(self.listOfColumnsFrames):
-			columnFrame.configure(width=ColumnWidthList[indexColumn], height=tableHeight)
-
+			if columnWidthList:
+				if columnWidthList[indexColumn] == 'auto':
+					columnWidth = self.columnWidthList[indexColumn]
+				else:
+					columnWidth = columnWidthList[indexColumn]
+			else:
+				columnWidth = self.columnWidthList[indexColumn]
+			
+			columnFrame.configure(width=columnWidth, height=tableHeight)
 			
 			if typeOfColumn == 'mobile':
 				if minsize == 'auto':
-					masterFrame.paneconfigure(columnFrame, minsize=ColumnWidthList[indexColumn])
+					masterFrame.paneconfigure(columnFrame, minsize=self.columnWidthList[indexColumn])
 				elif type(minsize) is int:
 					masterFrame.paneconfigure(columnFrame, minsize=minsize)
 				else:
@@ -72,7 +81,7 @@
 		
 		for i in range(self.numberOfRows):
 			for j in range(self.numberOfColumns):
-				self.gridOfCellWidgets[i][j].configure(height=RowHeightList[i])
+				self.gridOfCellWidgets[i][j].configure(height=self.rowHeightList[i])
 
 
 def test():
@@ -80,31 +89,35 @@
 
 	root = Tk()
 
-	numRows=4
-	numColumns= 5
-
-	tableGrid = []
-
-	listOfColors = ['blue', 'red','green', 'yellow']
-	listOfTexts = ['Something', 'Another thing', 'Word','This is still longer']
-
-	tkinterWidgets = [ Label, Button, Checkbutton]
-
-	for i in range(numRows):
-		row = []
-		for j in range(numColumns):
-			row.append(
-					[random.choice(tkinterWidgets),
-						{   'bg':random.choice(listOfColors),
-							'text':random.choice(listOfTexts)
-						}
-					]
-				)
-		tableGrid.append(row)
+	def build_random_table(master, numRows,numColumns, minsize, fixedColumns, columnWidthList = None):
+		import ttk
+		
+		tkinterWidgets =  (
+					(Label, {'text':'This is a label'}), 
+					(Label, {'text':'This is another label', 'bg':'yellow'}),
+					(Checkbutton,{}),
+					(Button, {'text':'Click me'}),
+					(ttk.Combobox, {'values':('item1', 'item2','item3','item4')})
+					)
+		tableGrid = []
 
 
-	PannedGrid(root, tableGrid,minsize=20,fixedColumns=[0,1]).pack(expand=YES, fill=X, pady=2, padx='2m')
+		for i in range(numRows):
+			row = [random.choice(tkinterWidgets) for j in range(numColumns) ]
 
+			tableGrid.append(row)
+
+		PannedGrid(master, tableGrid,minsize=minsize,fixedColumns=fixedColumns, columnWidthList=columnWidthList).pack(anchor=NW,pady=2, padx='2m')
+
+	Label(root, text="minsize = 20, fixed columns = [2,5]").pack(anchor=NW, pady=6, padx='2m') 
+	build_random_table(root, numRows=4,numColumns=6, minsize=20, fixedColumns=[2,5])	
+
+	emptySpace = Frame(root, height =30)
+	emptySpace.pack()
+	
+	Label(root, text="minsize = auto, fixed columns = [2,5], columnWidthList=[200, 'auto', 200, 'auto', 250, 'auto']").pack(anchor=NW, pady=6, padx='2m') 
+	build_random_table(root, numRows=4,numColumns=6, minsize='auto', columnWidthList=[200, 'auto', 200, 'auto', 250, 'auto'], fixedColumns=[2,5])
+	
 	root.mainloop()
 
 

History