I am writing a simple spreadsheet viewer. What I want is for row 0 to be controls and not scroll, Row 1 to be column headers and scroll horizontally with the data, rows 2 through end -1 to be data and scroll scroll both horizontally and vertically and a scroll bar at the far right, and the end row to be the horizontal scroll bar. I want the program to fill the entire window. What I have now is only the top left quarter of the window is used, horizontal scrolling works but there is no data and no vertical scroll bar.
import tkinter as tk
from tkinter import messagebox
def NewFrame(parent,d,ro = 0, co = 0, st = "NEWS", w = 1):
fr = tk.Frame(parent, **d)
fr.grid(row=ro,column=co, sticky=st)
fr.grid_columnconfigure(co, weight=w)
fr.grid_rowconfigure(ro, weight=w)
return fr
def NewCanvas(parent,d,ro = 0, co = 0, st = "NEWS", w = 1):
ca = tk.Canvas(parent, **d)
ca.grid(row=ro,column=co, sticky=st)
ca.grid_columnconfigure(co, weight=w)
ca.grid_rowconfigure(ro, weight=w)
return ca
class test:
def __init__(self,root,hxw):
self.hxw=hxw
root.wm_title("Test")
root.configure(bd=2)
root.configure(background="black")
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
if not self.hxw:
self.hxw='{0:d}x{1:d}+{2:d}+{3:d}'.format(min(940,screen_width),min(560,screen_height),int(screen_width/3),int(screen_height/3))
root.geometry(self.hxw) #Width x Height
root.update()
self.top = root
self.topFrame = NewFrame(self.top, {'height':25, 'background':"blue"}, st="NEW")
tk.Button(self.topFrame, text="Help", command=self.callback4).grid(row=0, column=0, sticky='E')
self.hsFrame = NewFrame(self.top, {'background':"red"}, st="NEW", ro=1)
self.hcanvas = NewCanvas(self.hsFrame, {'background':"green"}, st="NEW")
self.mFrame = NewFrame(self.hcanvas,{})
self.mFrame.bind(
"<Configure>",
lambda e: self.hcanvas.configure(
scrollregion=self.hcanvas.bbox("all")
)
)
self.hcanvas.create_window((0, 0), window=self.mFrame, anchor="nw")
# Create a horizontal scrollbar linked to the canvas.
hsbar = tk.Scrollbar(self.hsFrame, orient=tk.HORIZONTAL, command=self.hcanvas.xview)
hsbar.grid(row=2, column=0, sticky=tk.EW)
self.hcanvas.configure(xscrollcommand=hsbar.set)
self.labelFrame = NewFrame(self.mFrame, {'background':"grey", 'height':25}) #place a frame on the canvas, this frame will hold the child widgets
for col in range(20):
tkl = tk.Label(self.labelFrame, width=20, borderwidth="1", relief="solid", text=("col %d" % (col+1)))
tkl.grid(row=0, column=col, sticky='news')
self.labelFrame.grid_columnconfigure(col,weight=1)
self.vsFrame = NewFrame(self.mFrame, {'background':"yellow"})
self.vcanvas = NewCanvas(self.vsFrame, {'background':"#ff00ff"})
self.botFrame = NewFrame(self.vcanvas, {'background':"orange"}) #place a frame on the canvas, this frame will hold the child widgets
self.botFrame.bind(
"<Configure>",
lambda e: self.vcanvas.configure(
scrollregion=self.vcanvas.bbox("all")
)
)
self.vcanvas.create_window((0, 0), window=self.vsFrame, anchor="nw")
## # Create a vertical scrollbar linked to the canvas.
self.vsbar = tk.Scrollbar(self.vsFrame, orient=tk.VERTICAL, command=self.vcanvas.yview)
self.vsbar.grid(row=0, column=1, sticky=tk.NS)
self.vcanvas.configure(yscrollcommand=self.vsbar.set)
#
# Add 50-by-20 labels to the frame
rows = 50
columns = 20
for i in range(0, rows):
for j in range(0, columns):
tkl = tk.Label(self.botFrame, width=10, borderwidth="1", relief="solid", text=("%d,%d" % (i+1, j+1)))
tkl.grid(row=i, column=j, sticky='news')
self.botFrame.grid_columnconfigure(j, weight=1)
def callback4(self):
print('root', root.winfo_geometry())
print('self.topFrame', self.topFrame.winfo_geometry())
print('self.hsFrame', self.hsFrame.winfo_geometry())
print('self.hcanvas', self.hcanvas.winfo_geometry())
print('self.mFrame', self.mFrame.winfo_geometry())
print('self.labelFrame', self.labelFrame.winfo_geometry())
print('self.vsFrame', self.vsFrame.winfo_geometry())
print('self.vcanvas', self.vcanvas.winfo_geometry())
print('self.botFrame', self.botFrame.winfo_geometry())
print('------------------------------')
messagebox.showinfo(
"help",
"This is help"
)
# Launch the GUI
root = tk.Tk()
test(root,None)
root.mainloop()