3

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))
0

4 Answers 4

6
+50

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('/'):
    ...
Sign up to request clarification or add additional context in comments.

3 Comments

Wow... it worked with: action = tk.Button(win, text="To .csv", command=lambda:munge(input_directory.get(),output_directory.get())). However, I would like to know if this is the correct way to do this, do the previous solution is a pythonic way to solve this issue?.
@john_doe: The better way is for command=some_function, and then have some_function get the variables. In my opinion, lambda should only be used if it's strictly necessary.
Could you provide an example?. Just to give you the bounty?
1

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.

4 Comments

Thanks for the help, I tried your approach: action = tk.Button(win, text="To .csv", command=lambda:munge(input_directory,output_directory)). However, I still get the same error, any idea of why is happening this issue?.
the error you are getting is related to your function, the lambda will help you execute your function when you actually click on the button rather than onload. "How can I correctly call the aforementioned function with the help of the button"
The thing is that I have been using this functions for an argparse menu, and they actually worked perfect. On the other hand, this issue started when I tryed to start using Tkinter's StringVar()object. What should I do?
While you've pointed out a bug in the code, it's not the bug that's being asked about.
1

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.