python tkinter passing variables between functions

2020-05-01 03:32发布

问题:

I am trying to pass the variable dirpath into the export_data() function. Export data runs off of a double click on a button located on a widget. Why is dirpath printing as:

`<Tkinter.Event instance at 0x8ade56c>` 

instead of the actual path?

def export_data(dirpath):
    print 'exporting...'
    print str(dirpath)
    os.mkdir('/home/bigl/Desktop/Library')
    shutil.copytree(dirpath, output_path)

When I run my code I get the error

exporting...
<Tkinter.Event instance at 0x8ade56c>
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__
    return self.func(*args)
  File "/media/LOFTUS/20130308_searchtest.py", line 44, in export_data
    shutil.copytree(dirpath, output_path)
  File "/usr/lib/python2.7/shutil.py", line 169, in copytree
    names = os.listdir(src)
TypeError: coercing to Unicode: need string or buffer, instance found

回答1:

In the body of the question you asked:

Export data runs off of a double click on a button located on a widget. Why is dirpath printing as:

<Tkinter.Event instance at 0x8ade56c>

When you bind to an event, the binding always sends an event object as a parameter to the bound function. So, if you're doing:

widget.bind("<Double-1>", export_data)

... then export_data will receive the event as it's only parameter.

To pass a variable, you need to use lambda or functools.partial or some sort of function generator. For example:

widget.bind("<Double-1>", lambda event: export_data(dirpath))

Be careful with this, however. The value passed to export_data will be the value of dirpath at the time the event occurs, which may be different than the value when you creating the binding.

If you have a local variable that you want to pass to the function you can set it as a default value to a keyword argument, in which case the value at the time the lambda is created will be passed.

Example:

path = some_function()
widget.bind("<Double-1>", lamba event, dirpath=path: export_data(dirpath))


回答2:

Obviously Tkinter passes an event, not a string, to your callback. If dirpath is a global variable (as you wrote before-- important information!), perhaps you meant to define your callback like this:

def export_data(_ignored):
    print 'exporting...'
    print str(dirpath)
    os.mkdir('/home/bigl/Desktop/Library')
    shutil.copytree(dirpath, output_path)

Now your function can use the global dirpath (and output_path). The way you had it, the argument declaration was hiding the global of the same name.