I'm trying to write a python class to display data in a tabular format. I'm sure there are classes out there already to do the same thing, however, I'm using this exercise as a way to teach myself Python and tkinter. For the most part, I have the class working the way I want it to, however I cannot get the header and data cells to fill their entire cell, while being aligned left. Here is what my class currently generates for a table:
I went ahead and changed the sticky on the cells to be (W,E) rather than just W, in order to show how I want the table to look, except each cell left justified. Below is what I'm shooting for:
Based on the research I've done, it would seem I need to be using the weight
attribute of grid_columnconfigure
and grid_rowconfigure
, however every way I have tried using them I cannot, get it to work.
Here is the code for my class (I am using Python 3.4):
from tkinter import *
from tkinter import ttk
from tkinter import font
class TableData:
def __init__(self,parent,attributes,columns,data):
self.parent = parent
self.tableName = StringVar()
self.tableName.set(attributes['tableName'])
self.columns = columns
self.columnCount = 0
self.borderColor = attributes['borderColor']
self.titleBG = attributes['titleBG']
self.titleFG = attributes['titleFG']
self.titleFontSize = attributes['titleFontSize']
self.headerBG = attributes['headerBG']
self.headerFG = attributes['headerFG']
self.headerFontSize = attributes['headerFontSize']
self.dataRowColor1 = attributes['dataRowColor1']
self.dataRowColor2 = attributes['dataRowColor2']
self.dataRowFontSize = attributes['dataRowFontSize']
self.dataRowFG = attributes['dataRowFG']
self.data = data
self.tableDataFrame = ttk.Frame(self.parent)
self.tableDataFrame.grid(row=0,column=0)
self.initUI()
def countColumns(self):
cnt = 0
for i in self.columns:
cnt += 1
self.columnCount = cnt
def buildTableTitle(self):
tableTitleFont = font.Font(size=self.titleFontSize)
Label(self.tableDataFrame,textvariable=self.tableName,bg=self.titleBG,fg=self.titleFG,font=tableTitleFont, highlightbackground=self.borderColor,highlightthickness=2).grid(row=0,columnspan=self.columnCount,sticky=(W,E), ipady=3)
def buildHeaderRow(self):
colCount = 0
tableHeaderFont = font.Font(size=self.headerFontSize)
for col in self.columns:
Label(self.tableDataFrame,text=col,font=tableHeaderFont,bg=self.headerBG,fg=self.headerFG,highlightbackground=self.borderColor,highlightthickness=1).grid(row=1,column=colCount,sticky=W, ipady=2, ipadx=5)
colCount += 1
def buildDataRow(self):
tableDataFont = font.Font(size=self.dataRowFontSize)
rowCount = 2
for row in self.data:
if rowCount % 2 == 0:
rowColor = self.dataRowColor2
else:
rowColor = self.dataRowColor1
colCount = 0
for col in row:
Label(self.tableDataFrame,text=col,bg=rowColor,fg=self.dataRowFG,font=tableDataFont,highlightbackground=self.borderColor,highlightthickness=1).grid(row=rowCount,column=colCount,sticky=W,ipady=1, ipadx=5)
colCount += 1
rowCount += 1
def initUI(self):
self.countColumns()
self.buildTableTitle()
self.buildHeaderRow()
self.buildDataRow()
Here is a test file referencing the TableData class:
from tkinter import *
from tkinter import ttk
from tableData import TableData
import sqlite3
root = Tk()
root.geometry('1000x400')
mainframe = ttk.Frame(root).grid(row=0,column=0)
attributes = {}
attributes['tableName'] = 'Title'
attributes['borderColor'] = 'black'
attributes['titleBG'] = '#1975D1'
attributes['titleFG'] = 'white'
attributes['titleFontSize'] = 16
attributes['headerBG'] = 'white'
attributes['headerFG'] = 'black'
attributes['headerFontSize'] = 12
attributes['dataRowColor1'] = 'white'
attributes['dataRowColor2'] = 'grey'
attributes['dataRowFontSize'] = 10
attributes['dataRowFG'] = 'black'
columns = ['Col 1', 'Column 2', 'Column 3','Column 4']
results = [('1','Key','Desc','Attribute'),('2','Key Column','Description Column','AttributeColumn')]
table = TableData(mainframe,attributes,columns,results)
root.mainloop()
Thanks in advance for any insight. Please, let me know if there is any other info that would be helpful.
Python - Tkinter grid() Method This geometry manager organizes widgets in a table-like structure in the parent widget.
Tkinter can support the creation of more than one widget in the same frame. Not just this it also supports a mechanism to align them relative to each other. One of the easiest ways of aligning the different widgets in the Tkinter is through grid manager.
Tkinter has three built-in layout managers that use geometric methods to position buttons in an application frame: pack, grid, and place. The pack manager organizes widgets in horizontal and vertical boxes that are limited to left, right, top, bottom positions offset from each other.
Just give the row and column in which the label appears a weight of 1 and be sure not to specify a sticky attribute. By default the row and column weight is set to zero, which means neither will grow to fill in any extra space in the widget.
If you want the text in a label to be left-aligned, use the anchor option. It takes a string representing a point on a compass (eg: "w" = "west", meaning the text is anchored to the left):
for col in row:
Label(..., anchor="w").grid(...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With