I'm a little bit stuck on this problem regarding my program. I tried adding as many comments as possible to give a sense of what everything does in the code, but essentially. The program has a field and value entry box. When the "add field/value button" is clicked, more of the entry widgets are added. If this keeps occurring then obviously it'll go off screen. So I've limited the size of the application, but the problem then is I need a scrollbar. I've tried looking it up, but my frame uses grid, and everywhere they use pack which isn't compatible in this case. I get the scrollbar to appear, however it doesn't seem to work. I've seen some people use canvas, and more than one frame, etc. I'm missing something important but I don't know how do the exact same thing with a grid. Think you experts can lend me hand to get it working?
from tkinter import *
import tkinter as tk
class Insert(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
container = tk.Frame(self)
container.grid_columnconfigure(0, weight=1)
container.grid_rowconfigure(0, weight=1)
container.pack(side="top", fill="both", expand=True)
self.frameslist = {}
for frame in (Create,):
frame_occurrence = frame.__name__
active_frame = frame(parent=container, controller=self)
self.frameslist[frame_occurrence] = active_frame
active_frame.grid(row=0, column=0, sticky="snew")
self.show_frame("Create")
def show_frame(self, frame_occurrence):
active_frame = self.frameslist[frame_occurrence]
active_frame.tkraise()
class Create(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#For all widgets (nested list, 2 widgets per row)
self.inputlist = []
#For just the entries
self.newinputlist = []
#Create two labels, add them into the inputlist to be iterated
labels = [tk.Label(self, text="Field"), tk.Label(self, text="Values")]
self.inputlist.append(labels[:])
#Insert the labels from the list
for toplabels in range(1):
self.inputlist[toplabels][0].grid(row=toplabels, column=0, padx=10, pady=5)
self.inputlist[toplabels][1].grid(row=toplabels, column=1, padx=10, pady=5)
#Create the first two entry boxes, append them to the inputlist, and newinput list
first_entries = [tk.Entry(self, borderwidth=5), tk.Text(self, borderwidth=5, height= 5, width=20)]
self.newinputlist.append(first_entries[:])
self.inputlist.append(first_entries[:])
#Insert the entries from the newinputlist
for x in range(0, len(self.newinputlist) + 1):
self.newinputlist[0][x].grid(row=1, column=x, padx=10, pady=5)
#Create two buttons (Both share same row), append them to list
button_input_1 = [tk.Button(self, text="ADD FIELD/VALUE", command=self.add_insert), tk.Button(self, text="BACK")]
self.inputlist.append(button_input_1[:])
#Insert buttons at the bottom of the grid
for button in range(len(self.inputlist) - 2, len(self.inputlist)):
self.inputlist[button][0].grid(row=button, column=0, padx=10, pady=5)
self.inputlist[button][1].grid(row=button, column=1, padx=10, pady=5)
def add_insert(self):
#Create two new entries, append them to the list
add_input = [tk.Entry(self, borderwidth=5), tk.Text(self, borderwidth=5, height= 5, width=20)]
self.inputlist.insert(-1, add_input)
self.newinputlist.append(add_input)
#Because there are new entry boxes, old grid should be forgotten
for widget in self.children.values():
widget.grid_forget()
#Use the index for the row, get all widgets and place them again
for index, widgets in enumerate(self.inputlist):
widget_one = widgets[0]
widget_two = widgets[1]
widget_one.grid(row=index, column=0, padx=10, pady=5)
widget_two.grid(row=index, column=1, padx=10)
#Create scrollbar when this button is pressed
scrollbar = tk.Scrollbar(self, orient="vertical")
scrollbar.grid(row=0, column=2, stick="ns", rowspan=len(self.inputlist) + 1)
if __name__ == "__main__":
app = Insert()
app.maxsize(0, 500)
app.mainloop()