tkFileDialog не преобразует результаты в список Python в Windows - PullRequest
3 голосов
/ 10 февраля 2012

Я использую код ниже (Python 2.7 и Python 3.2), чтобы показать диалог открытия файлов, который поддерживает множественный выбор. В Linux имена файлов представляют собой список 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)

Ответы [ 4 ]

3 голосов
/ 10 февраля 2012

Проблема заключается в «интересном» взаимодействии между Tcl, Tk и Python, каждый из которых делает что-то разумное само по себе, но когда комбинация ведет себя неправильно.Глубокая проблема заключается в том, что Tcl и Python имеют очень различные представления о том, что означают типы, и это проявляется в качестве значения, которое Tcl видит в виде списка, но Python видит в виде строки (при этом код в Tk предполагаетчто не нужно быть осторожным, чтобы быть чистым для Python).Возможно, интерфейс Python должен использовать тот факт, что он может знать, что список Tcl будет возвращаться из множественного выбора, и скрывать это, но это не так, что вы застряли.

Я могу (и должен!) Исправьте это в Tk, но я не знаю, сколько времени потребуется, чтобы исправление вернулось к вам таким путем.


[EDIT]: теперь это исправлено (с это исправление) в ветке обслуживания Tk 8.5 и в основной ветке разработки.Я не могу предсказать, когда вы сможете получить фиксированную версию, если вы не возьмете источник из нашего ископаемого хранилища и не создадите его самостоятельно.

1 голос
/ 19 сентября 2012

По какой-то причине исправление на основе tk_eval не работает для меня. Имена файлов в строке, возвращаемой tkFileDialog, заключаются в квадратные скобки {} только в том случае, если они содержат пробелы, тогда как в документах tcl подразумевается, что все элементы списка должны быть разделены этими скобками.

В любом случае, вот исправление, которое, кажется, работает для меня (python 2.7.3 в Windows 7):

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
0 голосов
/ 19 февраля 2013

Быстрый способ, который я использовал:

filenames = filenames.strip('{}').split('} {')
0 голосов
/ 16 февраля 2012

Это исправление работает для меня:

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 /5277410/tkfiledialog-ne-preobrazuet-rezultaty-v-spisok-python-v-windows
    #
    # 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...