Optimal way to use tkinter and openpyxl to iterate through a spreadsheet? Optimal way to use tkinter and openpyxl to iterate through a spreadsheet? tkinter tkinter

Optimal way to use tkinter and openpyxl to iterate through a spreadsheet?


I'm working on something similar but with larger data.

I had a similar problem and I assume it occurs because of the processor trying to run both the excel iteration as well as the root.mainloop() on the same thread, which not only slows the process but also hangs your application making the GUI non-responsive. For this to work correctly, you will have to call your worker(Iteration) function in a different thread than your root.mainloop(). The best way to do this would be to define multiple classes for GUI, Worker and the App and call the Worker function threads from your App class while your GUI runs in a different loop.

A simple sample for the same-

import tkinter as tkfrom tkinter import ttk,messageboximport threadingimport time#base GUI Classclass GUI:    def __init__(self, root, runCommand):        mf = ttk.Frame(root, padding="5 5 5 5")        mf.grid(column=0, row=0)        mf.columnconfigure(0, weight=1)        mf.rowconfigure(0, weight=1)        # Global Values        self.Fnm = tk.StringVar(root, "SearchFile.xlsx")        self.Ncol = tk.StringVar(root, "D")        self.Vcol = tk.StringVar(root, "C")        # Label        tk.Label(mf, text="File Name").grid(column=1, row=1, pady=6)        tk.Label(mf, text="Name Col").grid(column=1, row=3, pady=6)        tk.Label(mf, text="Value Col").grid(column=3, row=3, pady=6)        # components        self.fname = ttk.Entry(mf, width=18, textvariable=self.Fnm)        self.nmCol = ttk.Entry(mf, width=6, textvariable=self.Ncol)        self.valCol = ttk.Entry(mf, width=6, textvariable=self.Vcol)        self.but = ttk.Button(mf, text="Refresh", command=runCommand)        self.pgbar = ttk.Progressbar(mf, orient="horizontal", mode="determinate")        # Design        self.fname.grid(column=2, row=1, pady=3, columnspan=3)        self.nmCol.grid(column=2, row=3, pady=3)        self.valCol.grid(column=4, row=3, pady=3)        self.but.grid(column=2, row=2, columnspan=2)        self.pgbar.grid(column=1,row=4,columnspan=4)    def refresh(self):        pass    def get(self):        return [self.Fnm.get(), self.Ncol.get(), self.Vcol.get()]#Base process Classclass Proc:    def __init__(self, dets,pgbar,but):        self.Fnm = dets[0]        self.Ncol = dets[1]        self.Vcol = dets[2]        self.pg=pgbar        self.butt=but    def refresh(self):        self.butt['state'] = 'disabled'        self.pg.start()        #ATTENTION:Enter Your process Code HERE        for _ in range(5):            time.sleep(2)#Longggg work        self.pg.stop()        #Any search/sort algorithm to be used        #You can use self.pg.step() to be more specific for how the progress bar proceeds        messagebox.showinfo("Process Done","Success")        self.butt['state'] = 'enabled'#Base Application Classclass App:    def __init__(self, master):        self.master = master        self.gui = GUI(self.master, self.runit)    def runit(self):        self.search = Proc(self.gui.get(),self.gui.pgbar,self.gui.but)        self.thread1 = threading.Thread(target=self.search.refresh)        self.thread1.start()def main():    app = tk.Tk()    gui = App(app)    app.title("Refresh Search File")    app.mainloop()if __name__ == '__main__':    main()

As for the iteration through the data, you can checkout this for a more efficient code.

I can't write all the code here as it is too long, so please refer the links