0

I am new to Tkinter and GUI design but I'm definitely excited to learn. I'm trying to create a user interface that allows a user to load an excel spreadsheet .xls. If the spreadsheet is successfully opened then a button should pop up allowing the user to import information into a database.

My problem is that whenever I run this code the file dialog pops up before the main gui with the actual browse button pops up. I did some tests and this behavior is due to calling fname.show(). The thing is, and please correct me if I'm wrong, I need to use fname.show() to get the filepath so that I can pass the filepath into the xlrd.open_workbook method to read data from the spreadsheet. Is there another way of getting the filename? I feel like there should be an easy solution but there isn't much in terms of documentation on the specifics of tkFileDialog.

Thanks.

Below is my code:

import config
from importdb import importTLAtoDB
import Tkinter as tk
import tkFileDialog as tkfd
import tkMessageBox as tkmb
import xlrd

def openFile():
    #returns an opened file
    fname = tkfd.Open(filetypes = [("xls files","*.xls")])
    fpath = fname.show()
    if fname:
        try:
            TLA_sheet = xlrd.open_workbook(fpath).\
                        sheet_by_name('Q3 TLA - TOP SKUs')
            tk.Button(root, text = "Import TLAs", command = importTLAtoDB(TLA_sheet)).pack()
            tkmb.showinfo("Success!", "Spreadsheet successfully loaded. \n\
Click Import TLAs to load TLA info into RCKHYVEDB database.")
        except:
            tkmb.showerror("Error", "Failed to read file\n '%s'\n\
Make sure file is a type .xls" % fpath)


#GUI setup
root = tk.Tk()
root.title("TLA Database Tool")
tk.Button(root, text = "Browse", command = openFile(), width = 10).pack()
root.mainloop()
user3761743
  • 145
  • 3
  • 14

2 Answers2

2

When you do, command = importTLAtoDB(TLA_sheet) you call the function and assign functions' value to command.

If you want to call a function with an argument, you need to use lambda or partials(there might be other options but these two are most preferred ones as far as I know).

So your Button line should be like this:

tk.Button(root, text="Import TLAs", command=lambda: importTLAtoDB(TLA_sheet)).pack()

Also, you may want to check this question. How to pass arguments to a Button command in Tkinter?

Community
  • 1
  • 1
Lafexlos
  • 7,618
  • 5
  • 38
  • 53
  • Thanks that worked! So by using a lambda function that calls the importTLAtoDB function, the lambda function won't be called until the button is pressed? – user3761743 Jun 27 '14 at 16:15
0
tk.Button(root, text = "Browse", command = openFile, width = 10).pack()

you dont want to actually call it when you setup the button

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Thanks this fixed the issue of the file dialog opening before clicking the button. Didn't realize that adding () invokes the function versus just command = functionname. – user3761743 Jun 27 '14 at 16:19