我正在使用下面的代码(Python 2.7和Python 3.2)来显示支持多选的“打开文件”对话框。在Linux上,filenames是一个python列表,但在Windows上,文件名返回为{C:/Documents and Settings/IE User/My Documents/VPC_EULA.txt} {C:/Documents and Settings/IE User/My Documents/VPC_ReadMe.txt}
,即原始TCL列表。
这是一个python错误,这里的任何人都知道将原始TCL列表转换为python列表的好方法吗?
if sys.hexversion >= 0x030000F0:
import tkinter.filedialog as filedialog
else:
import tkFileDialog as filedialog
options = {}
options['filetypes'] = [('vnote files', '.vnt') ,('all files', '.*')]
options['multiple'] = 1
filenames = filedialog.askopenfilename(**options)
答案 0 :(得分:3)
问题是Tcl,Tk和Python之间的“有趣”交互,每个交互都在做一些合理的事情,但是组合行为不正确。深层次的问题是Tcl和Python对于什么类型意味着非常不同的想法,这表现为Tcl看作列表的值,但Python看作是一个字符串(代码在Tk中)假设它不需要小心为Python清理)。可以说,Python界面应该使用这样一个事实:它可以知道一个Tcl列表将从多个选择中返回并隐藏它,但它不会让你被卡住。
我可以(而且应该!)在Tk修复此问题,但我不知道修复程序需要多长时间才能找到回复的方式。
[编辑]:现在已在Tk 8.5维护分支和主开发分支中修复(使用this补丁)。我无法预测何时能够获得固定版本,除非您从我们的化石库中获取源并自行构建它。
答案 1 :(得分:1)
出于某种原因,基于tk_eval的修复程序对我不起作用。 tkFileDialog返回的字符串中的文件名只包含在{}括号中,如果它们包含空格,而tcl文档似乎暗示所有列表项都应该用这些括号分隔。
无论如何,这是一个似乎对我有用的修复(Windows 7上的python 2.7.3):
def fixlist(filenames):
#do nothing if already a python list
if isinstance(filenames,list): return filenames
#http://docs.python.org/library/re.html
#the re should match: {text and white space in brackets} AND anynonwhitespacetokens
#*? is a non-greedy match for any character sequence
#\S is non white space
#split filenames string up into a proper python list
result = re.findall("{.*?}|\S+",filenames)
#remove any {} characters from the start and end of the file names
result = [ re.sub("^{|}$","",i) for i in result ]
return result
答案 2 :(得分:0)
此修复程序适用于我:
if sys.hexversion >= 0x030000F0:
import tkinter.filedialog as filedialog
string_type = str
else:
import tkFileDialog as filedialog
string_type = basestring
options = {}
options['filetypes'] = [('vnote files', '.vnt') ,('all files', '.*')]
options['multiple'] = 1
filenames = filedialog.askopenfilename(**options)
if isinstance(filenames, string_type):
# tkinter is not converting the TCL list into a python list...
# see http://stackoverflow.com/questions/9227859/
#
# based on suggestion by Cameron Laird in http://bytes.com/topic/python/answers/536853-tcl-list-python-list
if sys.hexversion >= 0x030000F0:
import tkinter
else:
import Tkinter as tkinter
tk_eval = tkinter.Tk().tk.eval
tcl_list_length = int(tk_eval("set tcl_list {%s}; llength $tcl_list" % filenames))
filenames = [] # change to a list
for i in range(tcl_list_length):
filenames.append(tk_eval("lindex $tcl_list %d" % i))
return filenames
答案 3 :(得分:0)
我用过的一种快捷方式:
filenames = filenames.strip('{}').split('} {')