Tkinter scrollbar initializes scrolled to bottom

Viewed 106

In Tkinter I've created a Frame that displays a bunch of data from a pandas DataFrame. To fit within the space I have in my real application, I need a Scrollbar. In the MRE below, I create some headers that I don't want to move and then the main data that should move along with the scrollbar. It almost works. The only problem is that the scrollbar initializes at the bottom of the dataset for some reason. I've worked with Tkinter for a long time and never had this happen.

I tried using can.yview_moveto(0) and placed that line in a few different spots in the loop sequence, but it doesn't seem to do anything.

Everything about this MRE has the behavior I want except for the initial position of the scrollbar.

import pandas as pd
import numpy as np
from tkinter import *
from tkinter import ttk

class TestClass(Frame):
    def __init__(self, parent=None):
        self.parent = parent
        Frame.__init__(self)
        self.main = self.master
        
        df = pd.DataFrame(np.random.randn(50, 5), 
                            columns=['A', 'B', 'C', 'D', 'E'])
        
        mf = Frame(self.parent)
        mf.pack()
        scroll = Scrollbar(mf, orient='vertical')
        scroll.pack(side='right', fill='y')
        can=Canvas(mf, yscrollcommand=scroll.set)
        can.pack(side='bottom', fill='both', expand=True)
        scroll.config(command=can.yview)
        qfrm = Frame(can)
        lfrm = Frame(mf) 
        lfrm.pack(side='top', fill='both', expand=True)
        can.create_window((0,0), window=qfrm, anchor='w')
        qfrm.bind('<Configure>', 
                lambda event, canvas=can: self.onFrameConfigure(canvas))
        (Label(lfrm, text='Title of the Frame')
                .grid(column=0, row=0, columnspan=5, pady=5))
        c=0
        w=6
        for d in df.columns:
            r=0
            #Inserts headers
            Label(lfrm, text=d, width=w).grid(column=c, row=1)
            for i in df.index:
                #Inserts data
                (Label(qfrm, text=round(df.loc[i, d], 2), width=w)
                        .grid(row=r, column=c, sticky=EW))
                r+=1
        
            c+=1
        can.yview_moveto(0)
        

    def onFrameConfigure(self, canvas):
        #Fixes scrollbar on tkinter canvas
        canvas.configure(scrollregion=canvas.bbox("all"))

if __name__ == '__main__':
    root=Tk()
    ui = TestClass(root)
    ui.pack()
    root.mainloop()
0 Answers
Related