Hide a column and resize table?
Meandmore opened this issue · comments
I am attempting to determine if there's a means to provide a column in a table and hide it, following with resizing the displayed table to match the remaining columns.
Hiding the column "Pos" (but table is sized incorrectly):
I have tried numerous methods but just cannot get the table size to shrink. Code:
import Tkinter`
#import tkintertable
from tkintertable import TableModel, TableCanvas
# ------------------------------------------------------------------------
# Start the main frame
# ------------------------------------------------------------------------
CAN_WIDTH = 1100
CAN_HEIGHT = 1100
app = Tkinter.Tk()
app.title('test_tkintertable')
app.grid_rowconfigure(0, weight=1)
app.grid_columnconfigure(0, weight=1)
# Make a canvas in which the frame will rest
CANVAS = Tkinter.Canvas(app)
CANVAS.grid(row=0, column=0, sticky="nsew")
CANVAS.configure(scrollregion=(0, 0, CAN_WIDTH, CAN_HEIGHT))
# Make a scrollbar attached to window - it will move the canvas
V_SCROLL = Tkinter.Scrollbar(app, orient='vertical')
V_SCROLL.config(command=CANVAS.yview)
CANVAS.config(yscrollcommand=V_SCROLL.set)
H_SCROLL = Tkinter.Scrollbar(app, orient='horizontal')
H_SCROLL.config(command=CANVAS.xview)
CANVAS.config(xscrollcommand=H_SCROLL.set)
# Place the scrollbar in grid
V_SCROLL.grid(row=0, column=30, sticky='ns')
H_SCROLL.grid(row=1, column=0, sticky='ew')
# Make the frame that will hold the widgets
FRAME = Tkinter.Frame(CANVAS, bd=0, relief='sunken')
FRAME.config(width=CAN_WIDTH, height=CAN_HEIGHT)
FRAME.grid(row=0, column=0)
# All other widgets will go in the frame
CANVAS.create_window(0, 0, window=FRAME, anchor="nw")
# Make a model
pricing_model = TableModel()
# Predefine the column order in the model before adding data
columns = ['Pos', 'Pool', 'Price']
for column in columns:
pricing_model.addColumn(column)
celldata = {'Item A': {'Pos':0, 'Pool':100, 'Price':10},
'Item B': {'Pos':1, 'Pool': 200, 'Price':0},
'Item C': {'Pos':2, 'Pool': 50, 'Price':5}
}
# Add the data using the data dictionary
pricing_model.importDict(celldata)
keys = celldata.keys()
num_cols = len(celldata[keys[0]])
num_rows = len(keys)
height_of_row = 30
colwidth = 50
table_width = colwidth * num_cols
table_height = 500
# Create the spreadsheet
table_height = height_of_row * num_rows
ssheet = TableCanvas(FRAME, model=pricing_model,
width=table_width, height=table_height,
cellwidth=colwidth, cellbackgr='#E3F6CE',
rowheight=height_of_row, editable=True,
rowselectedcolor='yellow',reverseorder=0,
rowheaderwidth=50, showkeynamesinheader=True)
ssheet.createTableFrame()
# Fill in the non-stored column widths
for column in columns:
pricing_model.columnwidths[column]=colwidth
# Sort rows in order of values in colindex column after table created
columns_in_table = pricing_model.columnNames
print 'columns_in_table = ', columns_in_table
colindex = columns_in_table.index('Pos')
ssheet.sortTable(columnIndex=colindex)
# TEST #1:
# Hide the sorting column and resize the table
pricing_model.columnwidths['Pos'] = 0
pos = ssheet.col_positions
print "pos =", pos
cols = ssheet.cols
print "cols = ", cols
widths = pricing_model.columnwidths
print "widths = ", widths
num_cols = num_cols - 1
table_width = colwidth * num_cols
ssheet.width = 50
ssheet.redrawTable()
# ------------------------------------------------------------------------
# Run the message-processing loop
# ------------------------------------------------------------------------
app.mainloop()
You would have to shrink the parent frame size, otherwise the table canvas just takes up whatever space is available from the parent. In your case you have a frame inside another canvas which you would have to resize somehow. Putting your widgets inside a canvas is a bit unusual.
Thank you - your comment got me thinking more clearly. I pieced together this code that works - it adds a canvas with window for controlling visibility. Since the table is a canvas, I thought that perhaps adding a window for the table might be more direct. I'm going to play with that, so I'm leaving the issue open for a day or so until I can test that idea.
import Tkinter
#import tkintertable
from tkintertable import TableModel, TableCanvas
# ------------------------------------------------------------------------
# Start the main frame
# ------------------------------------------------------------------------
CAN_WIDTH = 1100
CAN_HEIGHT = 1100
app = Tkinter.Tk()
app.title('test_tkintertable')
app.grid_rowconfigure(0, weight=1)
app.grid_columnconfigure(0, weight=1)
# ----------------------------------------------------------------------
# In order to scroll entire app window, build a canvas with scrollbars
# ----------------------------------------------------------------------
# Make a canvas in which the frame will rest
CANVAS = Tkinter.Canvas(app)
CANVAS.grid(row=0, column=0, sticky="nsew")
CANVAS.configure(width=CAN_WIDTH, height=CAN_HEIGHT, scrollregion=(0, 0, CAN_WIDTH, CAN_HEIGHT))
# Make a scrollbar attached to window - it will move the canvas
V_SCROLL = Tkinter.Scrollbar(app, orient='vertical')
V_SCROLL.config(command=CANVAS.yview)
CANVAS.config(yscrollcommand=V_SCROLL.set)
H_SCROLL = Tkinter.Scrollbar(app, orient='horizontal')
H_SCROLL.config(command=CANVAS.xview)
CANVAS.config(xscrollcommand=H_SCROLL.set)
# Place the scrollbar in grid
V_SCROLL.grid(row=0, column=30, sticky='ns')
H_SCROLL.grid(row=30, column=0, sticky='ew')
# ----------------------------------------------------------
# Make a frame to hold all widgets of the app in the canvas
# ----------------------------------------------------------
# Make the frame that will hold the widgets
FRAME = Tkinter.Frame(CANVAS, bd=0, relief='sunken')
FRAME.config(width=300, height=300)
FRAME.grid(row=0, column=0)
# ----------------------------------------------------------
# Make a window to control what is displayed of the canvas
# ----------------------------------------------------------
# Which frame do we want to control visibility over?
CANVAS.create_window(0, 0, window=FRAME, anchor="nw")
# Resize the canvas window
CANVAS.config(width=500, height=500)
# ----------------------------------------------------------------------
# In order to control what part of the table is visible, we need a canvas
# with window
# ----------------------------------------------------------------------
T_CANVAS = Tkinter.Canvas(FRAME)
T_CANVAS.grid(row=0, column=0, sticky="nsew")
T_CANVAS.configure(width=500, height=500)
# Make the frame that will hold the table
T_FRAME = Tkinter.Frame(T_CANVAS, bd=5, relief='sunken')
T_FRAME.grid(row=1, column=1)
# ----------------------------------------------------------
# Make a window to control what is displayed of the canvas
# ----------------------------------------------------------
T_CANVAS.create_window(0, 0, window=T_FRAME, anchor="nw")
# Make a model
pricing_model = TableModel()
# Predefine the column order in the model before adding data
columns = ['Pos', 'Pool', 'Price']
for column in columns:
pricing_model.addColumn(column)
celldata = {'Item A': {'Pos':0, 'Pool':100, 'Price':10},
'Item B': {'Pos':1, 'Pool': 200, 'Price':0},
'Item C': {'Pos':2, 'Pool': 50, 'Price':5}
}
# Add the data using the data dictionary
pricing_model.importDict(celldata)
keys = celldata.keys()
num_cols = len(celldata[keys[0]])
num_rows = len(keys)
height_of_row = 40
colwidth = 50
row_header_width = 75
col_header_height = 25
table_width = row_header_width + colwidth * num_cols
table_height = (height_of_row + 2) * num_rows
# Create the spreadsheet
ssheet = TableCanvas(T_FRAME, model=pricing_model,
width=300, height=300,
cellwidth=colwidth, cellbackgr='#E3F6CE',
rowheight=height_of_row, editable=True,
rowselectedcolor='yellow', reverseorder=0,
rowheaderwidth=row_header_width, showkeynamesinheader=True)
ssheet.createTableFrame()
# Fill in the non-stored column widths
for column in columns:
pricing_model.columnwidths[column]=colwidth
# Sort rows in order of values in colindex column after table created
columns_in_table = pricing_model.columnNames
print 'columns_in_table = ', columns_in_table
colindex = columns_in_table.index('Pos')
ssheet.sortTable(columnIndex=colindex)
# TEST #1:
# Hide the sorting column and resize the table
pricing_model.columnwidths['Pos'] = 0
num_cols = num_cols - 1
pos = ssheet.col_positions
print "pos =", pos
cols = ssheet.cols
print "cols = ", cols
print "colwidth = ", colwidth
widths = pricing_model.columnwidths
print "widths = ", widths
# Add 2 for borders
table_width = row_header_width + (colwidth+2) * num_cols
table_height = col_header_height + (height_of_row + 2) * num_rows
T_CANVAS.config(width=table_width, height=table_height)
ssheet.redrawTable()
#
# ------------------------------------------------------------------------
# Run the message-processing loop
# ------------------------------------------------------------------------
app.mainloop()