Reputation: 459
I have a tk
window with 3 frames, a left side that works like a tree structure with labels that will be added and removed with .grid()
and grid_remove()
, a right frame that will display information about these items, and a bottom frame that will hold buttons. If I expand too many items on the left frame(lframe) it pushes the bottom frame (bframe) out of view. I would rather the bottom frame stop when it gets to the edge of the window and the scrollbar for the lframe be used to view the items for lframe.
Here is a simple example of what im seeing. As you click the button more label widgets will be created and it will push the bframe
out of view.
from tkinter import *
main = Tk()
canvas = Canvas(main)
canvas.grid(row=0, column=0)
canvas.configure(scrollregion=canvas.bbox("all"))
lframe = Frame(canvas)
lframe.grid(row=0, column=1)
sbar = Scrollbar(canvas)
sbar.config(command=canvas.yview)
canvas.config(yscrollcommand=sbar.set)
sbar.grid(row=0, column=0, sticky=NSEW)
rframe = Frame(main)
rframe.grid(row=0, column=1, sticky=N)
bframe = Frame(main)
bframe.grid(row=1, column=1)
cnt = 1
def addmore():
global cnt
test = Label(lframe, text='this \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\n')
test.grid(row=cnt, column=0)
cnt += 1
lframe.update()
llbl = Label(lframe, text='this \nis \nthe \nLEFT \nframe')
llbl.grid()
rlbl = Label(rframe, text='this is the RIGHT frame')
rlbl.grid()
btn = Button(rframe, text='click me', command=addmore)
btn.grid(row=1, column=0, sticky=N)
blbl = Label(bframe, text='this is the BOTTOM frame', bg="yellow")
blbl.grid(row=0)
main.mainloop()
Question 1:
How can I stop the bframe from pushing off the screen? I want it to stop when it gets to the bottom of main
and the labels in lframe
start pushing out of view behind bframe
. Then the user would use the scrollbar to view the other items in lframe
.
Question 2: I wont know if my scrollbar is configured correctly until I can get the lframe to stop pushing off the screen. If its not setup right, what do I need to change?
Upvotes: 1
Views: 2948
Reputation: 15226
Here is an example of how you would set this scrolling canvas up with weights in the main frame. Its not perfect but it should be enough to help.
import tkinter as tk
class Example(tk.Frame):
def __init__(self):
tk.Frame.__init__(self)
self.canvas = tk.Canvas(self, borderwidth=0, width = 50, height = 100)
self.lframe = tk.Frame(self.canvas, width=10)
self.sbar = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.sbar.set)
self.sbar.grid(row=0, column=0, rowspan=2, sticky="nsw")
self.canvas.grid(row=0, column=1, rowspan=2, sticky="nsew")
self.canvas.create_window((2,2), window=self.lframe, anchor="ne",
tags="self.lframe")
self.lframe.bind("<Configure>", self.onFrameConfigure)
self.rframe = tk.Frame(self)
self.rframe.grid(row=0, column=2, sticky="n")
self.bframe = tk.Frame(self)
self.bframe.grid(row=1, column=2)
llbl = tk.Label(self.lframe, text='this \nis \nthe \nLEFT \nframe')
llbl.grid(row = 0, column = 0)
rlbl = tk.Label(self.rframe, text='this is the RIGHT frame')
rlbl.grid(row = 0, column = 0)
btn = tk.Button(self.rframe, text='click me', command=self.addmore)
btn.grid(row=1, column=0, sticky="n")
blbl = tk.Label(self.bframe, text='this is the BOTTOM frame', bg="yellow")
blbl.grid(row = 2, column = 0, sticky = "s")
self.bframe.rowconfigure(1, weight = 1)
self.bframe.rowconfigure(2, weight = 0)
self.rowconfigure(0, weight = 1)
self.rowconfigure(1, weight = 1)
self.columnconfigure(0, weight = 0)
self.columnconfigure(1, weight = 1)
self.columnconfigure(2, weight = 0)
self.cnt = 1
def addmore(self):
test = tk.Label(self.lframe, text='this \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\nthis \nis \nthe \nLEFT \nframe\n')
test.grid(row=self.cnt, column=0)
self.cnt += 1
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
if __name__ == "__main__":
root=tk.Tk()
Example().grid(row=0, column=0)
root.mainloop()
Upvotes: 1