3

I'm trying to get this program to print the contents of a .csv file onto a GUI.

I've created in Tkinter. It mostly works, but I can't figure out a way to get each button to print the contents of the file it's linked to.

At the moment I've created a variable that links to just one of the files, which shows that it works.

The variable is "loadFiles", and the project it's set to open is "a_P.csv". Is there any way I can make the buttons link this variable to the relevant .csv file?

The code is in this pastebin link: http://pastebin.com/ZP2pPvKA

The program searches for files ending in "_P.csv" in the same folder as it, so you may have to create a .csv with 7 objects in it.

2 Answers 2

1

I also tried this the way heinzderaugust suggested at first:

 button[i] = ttk.Button(loadProject, text=data_files[i], command = lambda i=data_files[i]:load(i)).grid(column=1, row=i, sticky=W)  

I was also able to solve this by using a class as the intermediary part of the callback: (This class was inserted inside viewProject )

class Command:
            def __init__(self, callback, *args, **kwargs):
                    self.callback = callback
                    self.args = args
                    self.kwargs = kwargs

            def __call__(self):
                    return(self.callback(*self.args, **self.kwargs))

Then I changed your button definition to:

button[i] = ttk.Button(loadProject, text=data_files[i], command = Command(load,data_files[i])).grid(column=1, row=i, sticky=W)     

And finally I changed the load function to accept a argument:

def load(myFile):                
            spamReader = csv.reader(open(myFile))
            for row in spamReader:
                    a = list(row)

            ttk.Label(loadProject, text=(a[0])).grid(column=4, row=0, sticky=W)
            ttk.Label(loadProject, text=("\n"+a[1])).grid(column=4, row=1, sticky=W)
            ttk.Label(loadProject, text=("\n"+a[2])).grid(column=4, row=2, sticky=W)
            ttk.Label(loadProject, text=(a[3])).grid(column=4, row=3, sticky=W)
            ttk.Label(loadProject, text=(a[4])).grid(column=4, row=4, sticky=W)
            ttk.Label(loadProject, text=("\n"+a[5])).grid(column=4, row=5, sticky=W)
            ttk.Label(loadProject, text=("\n"+a[6])).grid(column=4, row=6, sticky=W)
            ttk.Label(loadProject, text=("\n\n"+a[7])).grid(column=4, row=7, sticky=W)

I am unsure which would be best practice, but both do work.

(Certainly the lambda approach does sort of seem more 'pythonic')

Source: https://code.activestate.com/recipes/66521-avoiding-lambda-in-writing-callback-functions/

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I've got it working now. I went with the second one because it seems a bit easier to understand for me.
1

you can use a lambda function in order to pass an argument to your load function. Unfortunately pastebin ist down right now so i cannot have a look at your code. The idea is something like this:

for filename in filenames: ...Button(...,command=lambda i=filename:loadFile(i),...

so in your loadFile function you have the filename as first parameter

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.