Mensajes: 64
Temas: 28
Registro en: Apr 2018
Reputación:
0
Hola buenas tengo una aplicación muy sencilla en la que cargo un archivo .xlsx en un `dataframe` con la librería pandas y después genero un `treeview` para mostrarlo en modo de tabla. Con un archivo de 100 o 200 filas tarda muy poco, el problema viene cuando intento cargar un archivo con 2000 o 3000 registros que tarda alrededor de 1 minuto. Esto es normal? Hay alguna manera de optimizar esta operación?
En cualquier caso me gustaría incluir una barra de progreso de la librería Tkinter `ttk.Progressbar(parent, option=value, ...)` como esta, para así poder mostrar al usuario cuanto tiempo queda. Es esto posible? sincronizar el tiempo de cargado con el progreso de la barra?
Gracias, saludos!!
Mensajes: 1.300
Temas: 3
Registro en: Feb 2016
Reputación:
71
Hola Alfredo. Primero tendrías que determinar qué es lo que tarda: ¿cargar el archivo o agregar las filas a la vista de árbol?
Mensajes: 64
Temas: 28
Registro en: Apr 2018
Reputación:
0
06-09-2018, 06:18 AM
(Última modificación: 06-09-2018, 07:13 AM por alfredo89.)
Hola Francisco, lo que tarda es sin duda el tema de agregar las filas a la vista de arbol, el archivo lo carga en menos de un segundo, he intentado hacer un ejemplo pero con un archivo sin el texto original por temas de privacidad, no me tarda lo mismo.
Código: import pandas as pd
import tkinter as tk
from tkinter import ttk
def getTreeViewUser(df, frame):
tv = ttk.Treeview(frame, columns=("#1", "#2", "#3", "#4",'#5','#6','#7','#8','#9',
"#10","#11","#12","#13","#14","#15","#16","#17","#18"))
tv.heading('#0', text="Col0")
tv.heading('#1', text="Col1")
tv.heading('#2', text="Col2")
tv.heading('#3', text="Col3")
tv.heading('#4', text="Col4")
tv.heading('#5', text="Col5")
tv.heading('#6', text="Col6")
tv.heading('#7', text="Col7")
tv.heading('#8', text="Col8")
tv.heading('#9', text="Col9")
tv.heading('#10', text="Col10")
tv.heading('#11', text="Col11")
tv.heading('#12', text="Col12")
tv.heading('#13', text="Col13")
tv.heading('#14', text="Col14")
tv.heading('#15', text="Col15")
tv.heading('#16', text="Col16")
tv.heading('#17', text="Col17")
tv.heading('#18', text="Col18")
for ind in df.index:
# rojo = df.values[ind][17]
# tag=""
# if(rojo==1):
# tag="col18"
tv.insert("", tk.END, text=ind+1,
values=(df.values[ind][0],df.values[ind][1],
df.values[ind][2],df.values[ind][3],
df.values[ind][4],df.values[ind][5],
df.values[ind][6],df.values[ind][7],
df.values[ind][8],df.values[ind][9],
df.values[ind][10],df.values[ind][11],
df.values[ind][12],df.values[ind][13],
df.values[ind][14],df.values[ind][15],
df.values[ind][16],
df.values[ind][17]))
# tv.tag_configure('rojo', background='#F6CECE')
scrollbar_vertical = ttk.Scrollbar(frame, orient='vertical', command = tv.yview)
scrollbar_vertical.pack(side='right', fill=tk.Y)
scrollbar_horizontal = ttk.Scrollbar(frame, orient='horizontal', command = tv.xview)
scrollbar_horizontal.pack(side='bottom', fill=tk.X)
tv.configure(yscrollcommand=scrollbar_vertical.set)
tv.configure(xscrollcommand=scrollbar_horizontal.set)
return tv
def clickbutton():
file = pd.read_excel('Ejemplo.xlsx')
df = pd.DataFrame(file)
getTreeViewUser(df, main_window).pack(expand=True, fill='both')
class Application(ttk.Frame):
def __init__(self, main_window):
super().__init__(main_window)
main_window.geometry("600x500")
self.button = tk.Button(main_window, text="Button", command=clickbutton).pack()
self.progressbar = ttk.Progressbar(main_window)
self.progressbar.pack()
main_window = tk.Tk()
app = Application(main_window)
app.mainloop()
En este ejemplo el tiempo de carga es pequeño pero es porque el archivo .xlsx no es el original, no puedo compartirlo.
Edito mi pregunta y agrego el archivo que utilizo para simular mi error:
https://drive.google.com/open?id=147juWE...cWEakRy5iF
Mensajes: 1.300
Temas: 3
Registro en: Feb 2016
Reputación:
71
Alfredo, la idea es que llames a los métodos Progressbar.step() y Tk.update_idletasks() (que evita que se congele la ventana) en cada iteración del bucle que agrega las filas a la vista de árbol. Este ejemplo funciona sin dependencias:
Código: #!/usr/bin/env python
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk
def getTreeViewUser(df, frame):
tv = ttk.Treeview(frame, columns=("#1", "#2", "#3", "#4",'#5','#6','#7','#8','#9',
"#10","#11","#12","#13","#14","#15","#16","#17","#18"))
tv.heading('#0', text="Col0")
tv.heading('#1', text="Col1")
tv.heading('#2', text="Col2")
tv.heading('#3', text="Col3")
tv.heading('#4', text="Col4")
tv.heading('#5', text="Col5")
tv.heading('#6', text="Col6")
tv.heading('#7', text="Col7")
tv.heading('#8', text="Col8")
tv.heading('#9', text="Col9")
tv.heading('#10', text="Col10")
tv.heading('#11', text="Col11")
tv.heading('#12', text="Col12")
tv.heading('#13', text="Col13")
tv.heading('#14', text="Col14")
tv.heading('#15', text="Col15")
tv.heading('#16', text="Col16")
tv.heading('#17', text="Col17")
tv.heading('#18', text="Col18")
app.progressbar.config(maximum=10000)
for ind in range(10000):
tv.insert("", tk.END, text=ind+1, values=[i for i in range(18)])
app.progressbar.step()
main_window.update_idletasks()
scrollbar_vertical = ttk.Scrollbar(frame, orient='vertical', command = tv.yview)
scrollbar_vertical.pack(side='right', fill=tk.Y)
scrollbar_horizontal = ttk.Scrollbar(frame, orient='horizontal', command = tv.xview)
scrollbar_horizontal.pack(side='bottom', fill=tk.X)
tv.configure(yscrollcommand=scrollbar_vertical.set)
tv.configure(xscrollcommand=scrollbar_horizontal.set)
return tv
def clickbutton():
getTreeViewUser(None, main_window).pack(expand=True, fill='both')
class Application(ttk.Frame):
def __init__(self, main_window):
super().__init__(main_window)
main_window.geometry("600x500")
self.button = tk.Button(main_window, text="Button", command=clickbutton).pack()
self.progressbar = ttk.Progressbar(main_window)
self.progressbar.pack()
main_window = tk.Tk()
app = Application(main_window)
app.mainloop()
Deberías poder adaptarlo fácilmente a tu caso.
Saludos
|