Search code examples
pythondataframeuser-interfacetkintertreeview

Python Update info on Treeview without changing the size


I have this code where I Read from an Excel File and show it on a Treeview on a tkinter application. When the program starts the Treeview has a size but when I press the Button to open the file again it changes the size and leave a lot of non cover part. This is the code:

import pandas as pd
from tkinter import *
from tkinter import ttk, filedialog
import numpy as np
import datetime
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import plotly.express as px


def opendir():
    filename = filedialog.askopenfilename(
        initialdir="C:/Inversiones/",
        title="Open a File", filetype=(("xlsx files", "*.xlsx"),
                                       ("All Files", "*.*"))
    )
    LoadDashboard(filename)


def buttonopendir():
    filename = path
    LoadDashboard(filename)


def loadTable(Filename, SheetName):
    if Filename:
        try:
            filename = r"{}".format(Filename)
            df = pd.read_excel(filename, sheet_name=SheetName)
        except ValueError:
            lblFileStatus.config(text="File Couldn't opened...try again")
        except FileNotFoundError:
            lblFileStatus.config(text="File Couldn't found...try again")
    return df


def ONPanel():
    filename = path
    df = loadTable(filename, 'InfoONs')
    clear_tree(treeDashboard)
    tickerlist['Tickers'] = list(df['Ticker ARS'])

    treeDashboard["columns"] = list(df.columns)
    treeDashboard["show"] = "headings"

    ColWidth = [70, 70, 230, 115, 40,
                50, 45, 70, 80, 80,
                120, 80, 80, 80, 30,
                40, 115, 100, 70, 60]

    i = 0
    for column in treeDashboard["column"]:
        treeDashboard.column(column, width=ColWidth[i], stretch=NO)
        treeDashboard.heading(column, text=column, anchor=W)
        i += 1

    df_rows = df.to_numpy().tolist()
    for row in df_rows:
        treeDashboard.insert("", "end", values=row)
    my_scroll1.config(command=treeDashboard.yview)

    for col in treeDashboard["columns"]:
        treeDashboard.heading(
            col, text=col, command=lambda c=col: sort_treeview(treeDashboard, c, False))
    treeDashboard.config(selectmode="extended")
    treeDashboard.pack()


def clear_tree(tree):
    tree.delete(*tree.get_children())


def sort_treeview(tree, col, descending):
    data = [(tree.set(item, col), item) for item in tree.get_children('')]
    data.sort(reverse=descending)
    for index, (val, item) in enumerate(data):
        tree.move(item, '', index)
    tree.heading(col, command=lambda: sort_treeview(tree, col, not descending))


WIDTH = 1800
HEIGHT = 1000
path = 'C:/Inversiones/ONs.xlsx'
tickerlist = {}

root = Tk()
root.title("Obligaciones Negociables")
root.geometry(str(WIDTH)+"x"+str(HEIGHT))


# Recuadro para la Pestaña Dashboard
my_frame1 = ttk.Frame(root, border=5)
my_frame1.pack()


# Recuadro para los Botones
my_subframe = ttk.Frame(my_frame1)
my_subframe.pack()

btnOpenExcel = Button(my_subframe, text="Abrir Excel", command=ONPanel)
btnOpenExcel.grid(row=0, column=0, padx=30)
lblFileStatus = Label(my_subframe, text='Archivo sin actualizar')
lblFileStatus.grid(row=0, column=1, padx=30)

# Recuadro para el Dashboard
my_subframe2 = ttk.Frame(my_frame1, height=500, width=1625)
my_subframe2.pack()


my_scroll1 = Scrollbar(my_subframe2)
my_scroll1.pack(side=RIGHT, fill=Y)
treeDashboard = ttk.Treeview(
    my_subframe2, yscrollcommand=my_scroll1.set, selectmode="extended", height=37)
ONPanel()

# Configuro el menu
my_menu = Menu(root)
root.config(menu=my_menu)
file_menu = Menu(my_menu, tearoff=False)
my_menu.add_cascade(label="File", menu=file_menu)
file_menu.add_command(label="Open", command=opendir)

root.mainloop()

And this is the table From what I Read the data:

Ticker ARS Ticker USD Empresa Vencimiento Ley Dolar Pagos Min Nom VN colocado Amortizacion Industria Precio USD Volumen Precio ARS MD TIR Prox Cupon Dias Prox Cupon Dolar MEP Retorno
AEC1O AEC1D AES Argentina Generacion S.A 2025-07-14 00:00:00 ARG MEP Sem 1 30513915 Bullet Energia 107 3397074 88000 1,52 5,18 2024-01-14 00:00:00 78 822,43 116,02
ARC1O ARC1D Aeropuertos Argentina 2031-08-01 00:00:00 NY CABLE TRI 1000 208949631 No Bullet Turismo 99,4 105380784,6 83248 3,61 9,5 2023-11-01 00:00:00 4 837,51 144,68
CAC2O CAC2D Capex Clase 2 2024 2024-05-15 00:00:00 ARG CABLE SEM 1000 300000000 Bullet Energia 108 0 98000 0,54 -1,96 2023-11-15 00:00:00 18 907,41 106,88
CP17O CP17D COMPAÑIA GENERAL DE COMBUSTIBLES 2025-03-08 00:00:00 NY CABLE SEM 1000 196110000 No Bullet Energia 63 0 54745 0,93 6 2024-03-08 00:00:00 132 868,97 66,77
CP25O CP25D COMPAÑIA GENERAL DE COMBUSTIBLES S.A. 2024-02-25 00:00:00 ARG MEP TRI 1 11287128 Bullet Energia 109,5 0 99900 0,42 -20,57 2023-11-25 00:00:00 28 912,33 101,62

Solution

  • The easiest way I can think of how to fix it is to create the tk.TreeView again from scratch:

    import datetime
    from tkinter import *
    from tkinter import filedialog, ttk
    
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import plotly.express as px
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    
    
    def opendir():
        filename = filedialog.askopenfilename(
            initialdir=".",
            title="Open a File",
            filetype=(("xlsx files", "*.xlsx"), ("All Files", "*.*")),
        )
        LoadDashboard(filename)
    
    
    def buttonopendir():
        filename = path
        LoadDashboard(filename)
    
    
    def loadTable(Filename, SheetName):
        if Filename:
            filename = r"{}".format(Filename)
            df = pd.read_excel(filename, sheet_name=SheetName)
        return df
    
    
    def ONPanel():
        global treeDashboard
    
        if treeDashboard:
            treeDashboard.pack_forget()
    
        treeDashboard = ttk.Treeview(
            my_subframe2, yscrollcommand=my_scroll1.set, selectmode="extended", height=37
        )
    
        filename = path
        df = loadTable(filename, "InfoONs")
        clear_tree(treeDashboard)
        tickerlist["Tickers"] = list(df["Ticker ARS"])
    
        treeDashboard["columns"] = list(df.columns)
        treeDashboard["show"] = "headings"
    
        ColWidth = [
            70,
            70,
            230,
            115,
            40,
            50,
            45,
            70,
            80,
            80,
            120,
            80,
            80,
            80,
            30,
            40,
            115,
            100,
            70,
            60,
        ]
    
        i = 0
        for column in treeDashboard["column"]:
            treeDashboard.column(column, width=ColWidth[i], stretch=NO)
            treeDashboard.heading(column, text=column, anchor=W)
            i += 1
    
        df_rows = df.to_numpy().tolist()
        for row in df_rows:
            treeDashboard.insert("", "end", values=row)
        my_scroll1.config(command=treeDashboard.yview)
    
        for col in treeDashboard["columns"]:
            treeDashboard.heading(
                col, text=col, command=lambda c=col: sort_treeview(treeDashboard, c, False)
            )
        treeDashboard.config(selectmode="extended")
        treeDashboard.pack()
    
    
    def clear_tree(tree):
        tree.delete(*tree.get_children())
    
    
    def sort_treeview(tree, col, descending):
        data = [(tree.set(item, col), item) for item in tree.get_children("")]
        data.sort(reverse=descending)
        for index, (val, item) in enumerate(data):
            tree.move(item, "", index)
        tree.heading(col, command=lambda: sort_treeview(tree, col, not descending))
    
    
    WIDTH = 1800
    HEIGHT = 1000
    path = "data.xlsx"
    tickerlist = {}
    
    root = Tk()
    root.title("Obligaciones Negociables")
    root.geometry(str(WIDTH) + "x" + str(HEIGHT))
    
    
    # Recuadro para la Pestaña Dashboard
    my_frame1 = ttk.Frame(root, border=5)
    my_frame1.pack()
    
    
    # Recuadro para los Botones
    my_subframe = ttk.Frame(my_frame1)
    my_subframe.pack()
    
    
    btnOpenExcel = Button(my_subframe, text="Abrir Excel", command=ONPanel)
    btnOpenExcel.grid(row=0, column=0, padx=30)
    lblFileStatus = Label(my_subframe, text="Archivo sin actualizar")
    lblFileStatus.grid(row=0, column=1, padx=30)
    
    # Recuadro para el Dashboard
    my_subframe2 = ttk.Frame(my_frame1, height=500, width=1625)
    my_subframe2.pack()
    
    
    my_scroll1 = Scrollbar(my_subframe2)
    my_scroll1.pack(side=RIGHT, fill=Y)
    treeDashboard = None
    ONPanel()
    
    
    # Configuro el menu
    my_menu = Menu(root)
    root.config(menu=my_menu)
    file_menu = Menu(my_menu, tearoff=False)
    my_menu.add_cascade(label="File", menu=file_menu)
    file_menu.add_command(label="Open", command=opendir)
    
    root.mainloop()
    

    Creates this app (clicking on the open file will preserve the proportions):

    enter image description here