Posts: 34
Threads: 17
Joined: Dec 2019
Jul-11-2020, 08:01 PM
(This post was last modified: Jul-11-2020, 08:02 PM by kenwatts275.)
Hello all,
I cannot seem to get the column headers to align properly with my table.
The column headers have to be in a separate frame than the table, because I will be adding a scrollbar on the table. Below is a screenshot of the output and the code.
Any help would be appreciated.
Thanks in advance.
from tkinter import *
from tkinter import ttk
from pathlib import Path
def data_table(frame,col_widths):
# Create and populate values array
for i in range(0,max_rows):
values.append([])
j = 0
values[i].append(StringVar())
cb = ttk.Combobox(frame,width=col_widths[j],textvariable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(StringVar())
ent = Entry(frame,width=col_widths[j],textvariable=values[i][j])
ent.grid(row=i, column= j)
j += 1
values[i].append(StringVar())
ent = Entry(frame,width=col_widths[j],textvariable=values[i][j])
ent.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # readonly
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # Copy
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # mandatory
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(StringVar()) # sort order
ent = Entry(frame,width=col_widths[j],textvariable=values[i][j])
ent.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # removed
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
if __name__ == "__main__":
current_file = Path(__file__).stem
mw=Tk()
mw.geometry('1000x500+200+150')
mw.title(current_file)
frame4 = Frame(mw)
frame5 = Frame(mw)
frame4.pack(side=TOP,fill=X)
frame5.pack(side=TOP,fill=X)
headers = ["Field Name","Field Label","Default Value","ReadOnly","Copy","Mandatory","Sort Order","Remove"]
col_widths = [20,20,20,8,8,8,10,6]
column = 0
for header in headers:
l1 = Label(frame4,relief=FLAT,width=col_widths[column],text=header,anchor="w",justify="left")
l1.grid(row=0,column= column)
column += 1
values = []
max_rows = 10
data_table(frame5,col_widths)
mw.mainloop()
Posts: 1,145
Threads: 114
Joined: Sep 2019
Jul-11-2020, 09:21 PM
(This post was last modified: Jul-11-2020, 09:30 PM by menator01.)
Maybe this will get you started in the right direction.
#! /usr/bin/env python3
import tkinter as tk
root = tk.Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
mainframe = tk.Frame(root)
mainframe.grid(column=0, row=0, sticky='new')
mainframe.grid_columnconfigure(0, weight=3)
frame1 = tk.Frame(mainframe)
frame1.grid(column=0, row=0, sticky='new')
for i in range(1,4):
frame1.grid_columnconfigure(i, weight=3, uniform='columns')
for i in range(1, 4):
header = tk.Label(frame1, text=f'Header {i}')
header['relief'] = 'solid'
header['borderwidth'] = 1
header['highlightthickness'] = 1
header['highlightbackground'] = 'grey65'
header.grid(column=i, row=0, sticky='ew')
frame2 = tk.Frame(mainframe)
frame2.grid(column=0, row=1, sticky='new')
for i in range(1, 4):
frame2.columnconfigure(i, weight=3, uniform='table')
table_data = ['This is some data for row 1', 'Data for row 2', 'Data for row 3. This could be anything']
column = 1
for tdata in table_data:
data = tk.Label(frame2, text=tdata)
data['relief'] = 'solid'
data['borderwidth'] = 1
data['highlightthickness'] = 1
data['highlightbackground'] = 'grey65'
data.grid(column=column, row=0, sticky='ew')
column += 1
root.mainloop()
Posts: 34
Threads: 17
Joined: Dec 2019
Thanks for the response.
Setting the columns as uniform for both frames seems to fix the header alignment problem.
However, when I added a scrollbar to the second frame, the header alignment problem came back.
Also, the last column disappeared.
This probably has something to do with the canvas.
Any ideas on how to fix this would be appreciated.
Below is the code.
Thanks in advance.
from tkinter import *
from tkinter import ttk
from pathlib import Path
def data_table(frame,col_widths):
# Create and populate values array
for i in range(0,max_rows):
values.append([])
j = 0
values[i].append(StringVar())
cb = ttk.Combobox(frame,width=col_widths[j],textvariable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(StringVar())
ent = Entry(frame,width=col_widths[j],textvariable=values[i][j])
ent.grid(row=i, column= j)
j += 1
values[i].append(StringVar())
ent = Entry(frame,width=col_widths[j],textvariable=values[i][j])
ent.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # readonly
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # Copy
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # mandatory
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
j += 1
values[i].append(StringVar()) # sort order
ent = Entry(frame,width=col_widths[j],textvariable=values[i][j])
ent.grid(row=i, column= j)
j += 1
values[i].append(BooleanVar()) # removed
cb = ttk.Checkbutton(frame,width=col_widths[j],onvalue=1,offvalue=0,variable=values[i][j])
cb.grid(row=i, column= j)
def myfunction(event):
canvas.configure(scrollregion=canvas.bbox("all"),width=1000,height=350)
current_file = Path(__file__).stem
root = Tk()
root.geometry('1000x500+200+150')
root.title(current_file)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
mainframe = Frame(root)
mainframe.grid(column=0, row=0, sticky='new')
mainframe.grid_columnconfigure(0, weight=3)
headers = ["Field Name","Field Label","Default Value","ReadOnly","Copy","Mandatory","Sort Order","Remove"]
col_widths = [20,20,20,8,8,8,10,6]
frame1 = Frame(mainframe)
frame1.grid(column=0, row=0, sticky='new')
for i in range(8):
frame1.grid_columnconfigure(i, weight=3, uniform='columns')
for i in range(8):
header = Label(frame1, text=headers[i])
header['relief'] = 'raised'
header['borderwidth'] = 1
header['highlightthickness'] = 1
header['highlightbackground'] = 'grey65'
header.grid(column=i, row=0, sticky='ew')
frame2 = Frame(mainframe)
frame2.grid(column=0, row=1, sticky='new')
"""
for i in range(8):
frame2.columnconfigure(i, weight=3, uniform='table')
values = []
max_rows = 40
data_table(frame2,col_widths)
"""
canvas=Canvas(frame2)
frame=Frame(canvas)
myscrollbar=Scrollbar(frame2,orient="vertical",command=canvas.yview)
canvas.configure(yscrollcommand=myscrollbar.set)
myscrollbar.pack(side="right",fill="y")
canvas.pack(side="left")
canvas.create_window((0,0),window=frame,anchor='nw')
frame.bind("<Configure>",myfunction)
for i in range(8):
frame.columnconfigure(i, weight=3, uniform='table')
values = []
max_rows = 40
data_table(frame,col_widths)
root.mainloop()
Posts: 1,145
Threads: 114
Joined: Sep 2019
I've worked on this awhile and can't seem to get it align right and the scrollbar to work at the same time. Widths are right if you uncomment the scrollframe grid. But the scrollbar doesn't work. Maybe you can find a work around.
#! /usr/bin/env python3
import tkinter as tk
from tkinter import ttk
class MyClass:
def __init__(self, parent):
self.parent = parent
self.parent.columnconfigure(0, weight=1)
self.parent.rowconfigure(0, weight=1)
self.mainframe = tk.Frame(self.parent)
self.mainframe.grid(column=0, row=0, sticky='new')
self.mainframe.grid_columnconfigure(0, weight=3)
self.headerframe = tk.Frame(self.mainframe)
self.headerframe.grid(column=0, row=0, sticky='ew')
for i in range(0, 8):
self.headerframe.grid_columnconfigure(i, weight=3, uniform='header')
self.contentframe = tk.Frame(self.mainframe, bg='green')
self.contentframe.grid(column=0, row=1, sticky='new')
self.contentframe['relief'] = 'solid'
self.contentframe['borderwidth'] = 1
self.contentframe['highlightbackground'] = 'grey65'
self.contentframe['highlightthickness'] = 1
self.contentframe.grid_columnconfigure(0, weight=3)
canvas = tk.Canvas(self.contentframe, bg='pink')
scrollbar = ttk.Scrollbar(self.contentframe, orient='vertical', command=canvas.yview)
self.scrollframe = tk.Frame(canvas)
self.scrollframe.bind(
'<Configure>',
lambda event: canvas.configure(scrollregion=canvas.bbox('all'))
)
canvas.create_window((0, 0), window=self.scrollframe)
canvas.configure(yscrollcommand=scrollbar.set)
# You can comment this out and the scroll fame will work but, it shrinks
self.scrollframe.grid(column=0, row=0, sticky='news')
for i in range(0, 8):
self.scrollframe.grid_columnconfigure(i, weight=3, uniform='test')
scrollbar.grid(column=1, row=0, sticky='ns')
canvas.grid(column=0, row=0, sticky='news')
canvas.grid_columnconfigure(0, weight=3)
self.headers()
self.combo_box(40)
self.entrybox(1, 20, 5)
self.chkbox(3, 30)
self.entrybox(6,10, 15)
self.chkbox(7, 10)
def headers(self):
headers = ["Field Name","Field Label","Default Value","ReadOnly","Copy","Mandatory","Sort Order","Remove"]
col = 0
for header in headers:
label = tk.Label(self.headerframe)
label['text'] = header
label['relief'] = 'solid'
label['borderwidth'] = 1
label['highlightbackground'] = 'grey65'
label['highlightthickness'] = 1
label.grid(column = col, row=0, sticky='ew')
col += 1
def combo_box(self, howmany):
for i in range(0, howmany):
combobox = ttk.Combobox(self.scrollframe)
combobox.grid(column=0, row=i, sticky='new', padx=1)
def entrybox(self, col, howmany, padx):
row = 0
col = col
for i in range(0, howmany):
entry = tk.Entry(self.scrollframe)
entry.grid(column=col, row=row, sticky='new', padx=padx)
if row >= 9:
row = 0
col += 1
else:
row += 1
def chkbox(self, col, howmany):
row = 0
col = col
for i in range(0, howmany):
box = tk.Checkbutton(self.scrollframe)
box.grid(column=col, row=row)
if row >= 9:
row = 0
col += 1
else:
row += 1
def main():
root = tk.Tk()
root['padx'] = 10
root['pady'] = 5
root['relief'] = 'ridge'
root['borderwidth'] = 5
MyClass(root)
root.mainloop()
if __name__ =='__main__':
main()
|