john doe
john doe

Reputation: 2253

AttributeError: StringVar instance has no attribute 'endswith' while trying to call from a Tkinter button

I would like to create a GUI that receives two paths (a directory full of .txt documents and the destination of a new .csv file created from the files of the previously mentioned folder).

enter image description here

I am having trouble calling the function munge():

action = tk.Button(win, text="To .csv",command=munge(input_directory,output_directory))

Nevertheless, this exception raised:

/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /Users/user/PycharmProjects/script.py
Traceback (most recent call last):
  File "/Users/user/PycharmProjects/script.py", line 82, in <module>
    action = tk.Button(win, text="To .csv", command=munge(input_directory,output_directory))
  File "/Users/user/PycharmProjects/script.py", line 39, in munge
    test = tuple(retrive(directory))
  File "/Users/user/PycharmProjects/script.py", line 31, in retrive
    for filename in sorted(glob.glob(os.path.join(directory_path, '*.txt'))):
  File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.py", line 70, in join
    elif path == '' or path.endswith('/'):
AttributeError: StringVar instance has no attribute 'endswith'

Process finished with exit code 1

How can I correctly call the aforementioned function with the help of the Button widget?. I tried to set the name of the variable as indicated here question, but it did not worked.

update

Then from an answer of this question, I tried the following:

action = tk.Button(win, text="To .csv", command=lambda:munge(input_directory,output_directory))

Upvotes: 3

Views: 762

Answers (4)

Pythonista
Pythonista

Reputation: 11615

You want to call the .get() method on the StringVar to get the string it contains otherwise it's just the StringVar instance.

Upvotes: 1

john doe
john doe

Reputation: 2253

After all, it worked with: action = tk.Button(win, text="To .csv", command=lambda:munge(input_directory.get(),output_directory.get())). However, from Bryan Oakley answer I belive that this is not the correct way to do this.

Upvotes: 1

Bryan Oakley
Bryan Oakley

Reputation: 385830

Based on the error message, you seem to be trying to call the endswith method of a StringVar object. If you look at the documentation for such an object you'll see there's no such method. That is why you get the error that you do.

Assuming that path is an instance of a StringVar, you must call the get method in order to have the string stored by the object:

path_string = path.get()
if path_string == "" or path_string.endswith('/'):
    ...

Upvotes: 6

glls
glls

Reputation: 2403

You might want to consider reading a bit on callback functions in Tkinter, here is a useful link in order to do so http://effbot.org/zone/tkinter-callbacks.htm:

For simple cases like this, you can use a lambda expression as a link between Tkinter and the callback function:

def callback(number):
    print "button", number

Button(text="one",   command=lambda: callback(1))

your function is being executed as soon as your Button widget loads, you want to avoid this.

Upvotes: 1

Related Questions