I'd like to have a Frame
, where the user could add as many textfields as needed by the application.
The application starts with a textfield, and a button below that textfield. When the user presses the button, a new text entry will be added below the first one ( this may be repeated countless times ). In the middle of the window, there will be a Text
widget, used to display text :)
However, I noticed this in the documentation:
This widget is used to implement scrolled listboxes, canvases, and text fields.
Is there a way to use the Scrollbar
with a Frame
?
If you can use Tix, there is the ScrolledWindow widget which has a window
Frame and one or two Scrollbar widgets:
import Tix as tk
r= tk.Tk()
r.title("test scrolled window")
sw= tk.ScrolledWindow(r, scrollbar=tk.Y) # just the vertical scrollbar
sw.pack(fill=tk.BOTH, expand=1)
for i in xrange(10):
e= tk.Entry(sw.window)
e.pack()
r.mainloop()
Change the size of the root window. You will want to add code to the focus_get event of the Entry widgets to scroll the ScrolledWindow when tabbing through the keyboard.
Otherwise, you will have to use a Canvas widget (you can add Label, Entry and Text subwidgets) and write a lot more code yourself to implement your required functionality.
The following is an example of auto hiding scrollbars that only works if you just use the grid geometry manager, taken from the effbot.org
documentation:
from tkinter import *
class AutoScrollbar(Scrollbar):
# A scrollbar that hides itself if it's not needed.
# Only works if you use the grid geometry manager!
def set(self, lo, hi):
if float(lo) <= 0.0 and float(hi) >= 1.0:
# grid_remove is currently missing from Tkinter!
self.tk.call("grid", "remove", self)
else:
self.grid()
Scrollbar.set(self, lo, hi)
def pack(self, **kw):
raise TclError("cannot use pack with this widget")
def place(self, **kw):
raise TclError("cannot use place with this widget")
# create scrolled canvas
root = Tk()
vscrollbar = AutoScrollbar(root)
vscrollbar.grid(row=0, column=1, sticky=N+S)
hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)
canvas = Canvas(root, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
vscrollbar.config(command=canvas.yview)
hscrollbar.config(command=canvas.xview)
# make the canvas expandable
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
# create canvas contents
frame = Frame(canvas)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(1, weight=1)
rows = 5
for i in range(1, rows):
for j in range(1, 10):
button = Button(frame, text="%d, %d" % (i,j))
button.grid(row=i, column=j, sticky='news')
canvas.create_window(0, 0, anchor=NW, window=frame)
frame.update_idletasks()
canvas.config(scrollregion=canvas.bbox("all"))
root.mainloop()