Reputation: 45
So I want to have a vertical and horizontal scroll bar on the window that automatically updates for the size of the canvas. I got it partly there, and right now the code creates extra scroll bars for each update and the horizontal scroll bar doesn't span the length of the whole canvas. Here is a sample I created to illustrate this:
import tkinter
from tkinter import ttk
root = tkinter.Tk()
root.state("zoomed")
bigframe = tkinter.Frame(root)
bigframe.pack(fill="both", expand=1)
canvas = tkinter.Canvas(bigframe)
canvas.pack(side="left", fill="both", expand=1)
scrollbarv = ttk.Scrollbar(bigframe, orient="vertical", command=canvas.yview)
scrollbarh = ttk.Scrollbar(bigframe, orient="horizontal", command=canvas.xview)
scrollbarv.pack(side="right", fill="y")
scrollbarh.pack(side="bottom", fill="x")
canvas.configure(yscrollcommand=scrollbarv.set, xscrollcommand=scrollbarh.set)
canvas.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
mainframe = tkinter.Frame(canvas)
canvas.create_window((0, 0), window=mainframe, anchor="nw")
i = 1
text = "Hello World! "
def click():
global i
global text
for t in range(10):
i += 1
text += "Hello World! "
tkinter.Label(mainframe, text=text).pack()
scrollbar = ttk.Scrollbar(bigframe, orient="vertical", command=canvas.yview)
scrollbar.pack(side="right", fill="y")
button = tkinter.Button(mainframe, text="Click me!", command=click)
button.pack()
root.mainloop()
This is what happens when I click the button 4 times:
I believe the horizontal scrollbar being small is due to me saying canvas.pack(side="left", fill="both", expand=1)
, but if I say side="top
then the vertical scroll bars don't span the height of the canvas.
Is there some specific piece of code that is causing the multiple scrollbars issue or the horizontal bar issue? And if so, how should I fix it?
Upvotes: 0
Views: 1089
Reputation: 133
You have to destroy the old scrollbar before you add a new one. Just add scrollbar.destroy() to your click function, like I did below:
def click():
global i
global text
for t in range(10):
i += 1
text += "Hello World! "
tkinter.Label(mainframe, text=text).pack()
scrollbar = ttk.Scrollbar(bigframe, orient="vertical", command=canvas.yview)
scrollbar.destroy()
scrollbar.pack(side="right", fill="y")
I made the following changes to your code. At first it doesn't work, however if I resize the window it works perfectly.
import tkinter
from tkinter import ttk
root = tkinter.Tk()
root.state("zoomed")
bigframe = tkinter.Frame(root)
bigframe.pack(fill="both", expand=1)
canvas = tkinter.Canvas(bigframe)
canvas.pack(side="left", fill="both", expand=1)
scrollbarv = ttk.Scrollbar(bigframe, orient="vertical",
command=canvas.yview)
scrollbarh = ttk.Scrollbar(root, orient="horizontal",
command=canvas.xview)
scrollbarv.pack(side="right", fill="y")
scrollbarh.pack(side="bottom", fill="x")
canvas.configure(yscrollcommand=scrollbarv.set,
xscrollcommand=scrollbarh.set)
canvas.bind("<Configure>", lambda e:
canvas.configure(scrollregion=canvas.bbox("all")))
mainframe = tkinter.Frame(canvas)
canvas.create_window((0, 0), window=mainframe, anchor="nw")
i = 1
text = "Hello World! "
def updateScrollRegion():
canvas.update_idletasks()
canvas.config(scrollregion=mainframe.bbox())
def click():
global i, scrollbarv, text
for t in range(10):
i += 1
text += "Hello World! "
tkinter.Label(mainframe, text=text).pack()
button = tkinter.Button(mainframe, text="Click me!", command=click)
button.pack()
root.mainloop()
Upvotes: 1