There is a group of similar frames with some elements. I want to arrange these frames in the form of a column with a scrollbar on the right and pack the whole structure into one enclosing frame. I do this:
frame = Frame(mainWindow) # фрейм в котором будет расположен столбец фреймов с скроллом frame.grid() listbox = Listbox(dialogsFrame) listbox.pack(side = LEFT, fill = Y) scroll = Scrollbar(dialogsFrame) scroll.pack(side = RIGHT, fill = Y) listbox.config(yscrollcommand = scroll.set) scroll.config(command = listbox.yview)
And then I pack my frames[i].grid(row = i, column = 0)
in the listbox. The result is the desired design, but the scrollbar does not work. Those. there is no slider on it and it is not active at all. At the same time, by default, the frame
size is sufficient so that there is no slider on the scrollbar (that is, all subframes are visible). When resizing the window to achieve the appearance of the slider fails. Scrollbar want to do because it is possible that there will be too many subframes and the window will come out of the monitor. How to do it?
Outside the original frame in the window can be located other elements. I would like to make the design independent of the size of these elements and the frame itself. Those. if the user resizes the window, then at a certain point (if the window height is too small) the scrollbar is activated. I just want to set a limit on the window itself (for example, set the height of the window to a certain fraction of the vertical resolution) and resize restrictions on some elements adjacent to the frame, and let the frame itself resize as it wants, only so that the scrollbar appears and works correctly.
UDP [02.26.2016]: found this example in stackoverflow English . Based on it, I made the following test code:
from tkinter import * root = Tk() topButton = Button(root, text = 'Кнопка сверху') topButton.grid(row = 0, column = 0) lowFrame = Frame(root) lowFrame.grid(row = 1, column = 0) canvas = Canvas(lowFrame) frame = Frame(canvas) myscrollbar = Scrollbar(lowFrame, orient = 'vertical', command = canvas.yview) canvas.configure(yscrollcommand = myscrollbar.set) myscrollbar.pack(side = 'right', fill = Y) canvas.pack(side = 'left') canvas.create_window((0, 0), window = frame, anchor = 'nw') def conf(event): canvas.configure(scrollregion = canvas.bbox('all')) frame.bind('<Configure>', conf) for i in range(50): b = Button(frame, text = str(i)) b.grid(row = i, column = 0) root.mainloop()
It works fine, but a couple of questions arose:
- What does
canvas.create_window()
do? What is this window where it is created? - We bind the
frame.bind('<Configure>', conf)
. You can check that the event occurs every time you use the scroll. Why does a frame-related event occur when using a scroll? - What does this thing do:
canvas.configure(scrollregion = canvas.bbox('all'))
? Why does it need to be executed every time it is scrolled, why is it not enough to execute it once when the program is initialized? - Is there no way to bind an event (see 2 and 3) without explicitly defining an additional function in the program? Use lambda expressions, or something like that?