Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tkinter put scrollbar on canvas at bottom position

Question on scrollbar positions on my tkinter canvas. I have a frame with 3 canvas widgets. Courtesy to this post for the idea. I added a horizontal scrollbar and each canvas has a 50+ column 500+ row pandas dataframe. The load is not very fast but that isn't an objective.

New rows will be added to the bottom of each dataframe. This new row needs a validation. So instead of scrolling down every time, it would be great if the scrollbar / or canvas shows the bottom part.

See below the code where the 3x canvas and 3x scrollbars (x+y) are defined.

def createBox(window):
    list_ = ['df1', 'df2', 'df3'] # 3 dataframes

    for i in range(3):
            mybox = LabelFrame(window, padx=5, pady=4)
            mybox.grid(row=i, column=0)
            createWindow(mybox, list_[i], i)

def createWindow(box, lt_actual, i):
    canvas = Canvas(box, borderwidth=0)
    frame = Frame(canvas)
            vsbY = Scrollbar(box, orient="vertical", command=canvas.yview)
            canvas.configure(yscrollcommand=vsbY.set, width=1200, heigh=200) 
            vsbY.pack(side="right", fill="y")

            vsbX = Scrollbar(box, orient="horizontal", command=canvas.xview)
            canvas.configure(xscrollcommand=vsbX.set, width=1200, heigh=200)       
            vsbX.pack(side="bottom", fill="x")

    #canvas.yview_moveto(1) - no effect
    #canvas.yview_moveto(1.0) - no effect

    canvas.pack(side="left", fill="both", expand=True)
    canvas.create_window((4,4), window=frame, anchor="nw", tags="frame")

    # be sure that we call OnFrameConfigure on the right canvas
    frame.bind("<Configure>", lambda event, canvas=canvas: OnFrameConfigure(canvas))

I read on this forum and on some info (effbot) pages that i should use the moveto() / yview_moveto() command option but so far this doesn't seem to work.

Question 1. Should I put the y-scrollbar to the bottom or should i put the canvas view to the bottom.

Question 2. Can you provide some guidance on how to use the moveto or should I follow a different approach?

Thanks so much!

like image 384
John J. Johnson Avatar asked Jan 23 '17 10:01

John J. Johnson


2 Answers

The yview_moveto method of the canvas is indeed the right function to use. Its argument is the fraction of the total height of the canvas that you want off-screen. So using 0 as argument shows the top of the canvas and 1, the bottom.

Reference:

  • Tkinter.Canvas.yview_moveto-method
    Adjusts the canvas to the given Scroll offset.
    Offset '0.0' is the beginning of the scrollregion, '1.0' the end.

import tkinter as tk

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.grid(row=0, column=0)
canvas.create_oval(0, 0, 20, 20, fill='red')
canvas.create_oval(0, 800, 20, 820, fill='blue')

ys = tk.Scrollbar(root, orient='vertical', command=canvas.yview)
ys.grid(row=0, column=1, sticky='ns')
# configure scrolling
canvas.configure(yscrollcommand=ys.set, scrollregion=canvas.bbox('all'))
# show bottom of canvas
canvas.yview_moveto('1.0')

root.mainloop()

By the way, I don't see any difference between putting the y-scrollbar to the bottom or putting the canvas view to the bottom because the two are linked. But I guessed you wanted to know whether to do it using a method of the scrollbar or of the canvas, and I gave the answer above.

like image 52
j_4321 Avatar answered Sep 29 '22 09:09

j_4321


I have found that it is necessary to use idle_tasks before moving the scroll tab:

    self.canvas.update_idletasks()
    self.canvas.yview_moveto(0)
like image 20
Jim Robinson Avatar answered Sep 29 '22 08:09

Jim Robinson