Hi I have a frame in a canvas. I want to have a button that adds a text box to the frame every time the button is pressed. The text boxes are added to right of the text box before it, and once there are too many text boxes I want to be able to use the scrollbar to view all of them. But for some reason it isn't working. Thanks for any help in advance.
Here's the code:
from tkinter import *
import tkinter as tk # python 3
from tkinter import ttk
class Tkinter(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, SecondPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
frame.winfo_toplevel().geometry("1536x864")
frame.configure(bg='#151B1E')
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.canvas = Canvas(self, height=400, bg='black', highlightthickness=0, )
self.frame = tk.Frame(self.canvas)
self.frame.configure(bg='#151B1E')
self.frame.pack(fill='both', expand=True)
self.frame.bind("<Configure>", self.onFrameConfigure)
self.canvas.bind("<Configure>", self.onCanvasConfigure)
self.canvas.create_window((0, 0), window=self.frame, width=1336, anchor='nw', tags='self.frame')
self.canvas.place(x=20, y=200, relheight=0.7, relwidth=0.9674479167)
self.editbutton = Button(self, text='Add', command=lambda: self.add())
self.editbutton.pack()
self.myscrollbar = Scrollbar(self, orient="horizontal", command=self.canvas.xview)
self.myscrollbar.pack(side=BOTTOM, fill=X)
def onFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def onCanvasConfigure(self, event):
# width is tweaked to account for window borders
width = event.width - 4
self.canvas.itemconfigure("self.frame", width=width)
def add(self):
self.t = Text(self.frame, bg='#171D1F', fg='white', highlightcolor='#12171A', borderwidth=0, width=40)
self.t.pack(side=tk.LEFT, padx=20)
self.frame.update() # update frame2 height so it's no longer 0 ( height is 0 when it has just been created )
self.canvas.configure(xscrollcommand=self.myscrollbar.set, scrollregion="0 0 0 %s" % self.frame.winfo_width())
class SecondPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
app = Tkinter()
app.mainloop()
The problem is that you're forcing the width of the inner frame to be the width of the canvas. The reason why the frame-in-a-canvas works for scrolling is because the frame is allowed to be larger than the canvas. You need to remove the code that sets the width, or only set it to the width of the canvas if its natural width is less than the width of the canvas.
Here is where you're forcing it to a specific width:
self.canvas.create_window(..., width=1336, ...)
... and here:
self.canvas.itemconfigure("self.frame", width=width)