Python Tkinter 函数间传递变量

0 投票
2 回答
1448 浏览
提问于 2025-04-17 18:41

我想把变量 dirpath 传递给 export_data() 这个函数。export_data 是在一个小部件上的按钮被双击时运行的。为什么 dirpath 打印出来的是:

`<Tkinter.Event instance at 0x8ade56c>` 

而不是实际的路径呢?

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

当我运行我的代码时,我得到了这个错误:

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

2 个回答

0

显然,Tkinter 传递的是一个事件,而不是一个字符串,给你的回调函数。如果 dirpath 是一个全局变量(就像你之前写的那样——这很重要!),也许你应该这样定义你的回调函数:

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

现在你的函数可以使用全局的 dirpath(还有 output_path)。你之前的写法中,参数的声明遮住了同名的全局变量。

1

在你提问的内容中:

你提到:导出数据是通过双击一个小部件上的按钮来触发的。为什么 dirpath 打印出来是:

<Tkinter.Event instance at 0x8ade56c>

当你绑定一个事件时,这个绑定总是会把一个事件对象作为参数传递给绑定的函数。所以,如果你这样写:

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

...那么 export_data 函数就会接收到这个事件作为它唯一的参数。

如果你想传递一个变量,你需要使用 lambda 或者 functools.partial,或者其他一些函数生成器。比如:

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

不过要小心,这样做的话,传递给 export_data 的值将是 dirpath 在事件发生时的值,这个值可能和你创建绑定时的值不同。

如果你有一个局部变量想要传递给函数,可以把它设置为一个关键字参数的默认值,这样在创建 lambda 时的值就会被传递。

举个例子:

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

撰写回答