dmnfarrell / tkintertable

A pure Python library for adding tables to a Tkinter application

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

Showing the column "Pos":
showing

Hiding the column "Pos" (but table is sized incorrectly):
hidden

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()