2013-08-15 2 views
0

Как видно из названия, я пытаюсь использовать os.walk внутри главного магазина Tkinter. Я использую Python 3.3.0.Использование os.walk в главном окне Tkinter

По сути, у меня есть интерфейс, который при нажатии на кнопку, вы затем ввести для цикла, который перебирает элементы списка (в этом случае, они являются архивными именами, которые позже распакованы), а затем звонки цикл os.walk для выполнения некоторых вариантов сравнения. Это не было бы проблемой, если бы мне нечего было показывать в главном окне. Поскольку я ожидаю, что это займет некоторое время, я планировал добавить пару счетчиков времени для записи и оценить время, необходимое для выполнения полной операции.

Я знаю, что если я вхожу в для или в то время как петля внутри mainloop() я бы в конечном итоге голодающих mainloop, поэтому таймеры не будут обновлены до тех пор, пока цикл закончился. Я также знаю о w.update_idletasks(), но это только, кажется, обновляет материал внутри цикла.

Я знаю, что лучший способ петли в то время как внутри mainloop должен иметь вызов функции сам рекурсивно (через механизм обратного вызова или оператор возврата). Однако, поскольку os.walk является генератором, я не знаю, как его преобразовать в рекурсивную функцию.

Вот отрывок из (упрощенный) код в вопросе:

for file in ziplist: 
    try: 
     # some code in here 

     for dirpath, dirnames, filenames in os.walk(zipdirpath): 
      for files in filenames: 
       filepath = os.path.join(dirpath,files)[len(zipdirpath)+1:] 
       size += os.stat(os.path.join(dirpath,files)).st_size 
       print(filepath) 
       left.append(filepath) 
     print(size) 

     # some code in here 

    except: 
     # some code in here 

    finally: 
     # some code in here 

можно конвертировать (или, по крайней мере, я думаю, что я могу) первый цикл на что-то вроде этого:

def callback(): # to be called by Tkinter 
    def func(index=0): 
     if index > len(ziplist): 
      return 

     # some code in here 

     index += 1 
     func(index) 

Но я немного озадачен тем, как сделать то же самое с петлей os.walk. Следовательно, мой вопрос.

EDIT: Кажется, я нашел ответ. Если я использую next(os.walk(...)), я могу в итоге получить все, что мне понадобится (как кортеж). Тем не менее, я все еще хотел бы услышать некоторые другие ответы.

ответ

0

я, наконец, получил вокруг этого, и у меня есть «решение»:

Прежде, используя return function() заявления или просто вызывая function() заканчивает голодают цикл событий. Таким образом, я должен вызывать все соответствующие функции рекурсивно через w.after или w.after_idle.

Наконец, функции, вызывающие себя, включают в себя рекурсию, которая для некоторых длинных процессов может в конечном итоге привести к сбою программы, хотя кажется, что событие Tkinter eventloop полностью обходит эти вещи.


Оба эти ...

for dirpath, dirnames, filenames in os.walk(path): 
    print(dirpath, dirnames, filenames) 

... и эти ...

walk_object = os.walk(path) 
def func(): 
    global walk_object 
    try: 
     dirpath, dirnames, filenames = next(walk_object) 
     print(dirpath, dirnames, filenames) 
     func() # or w.after(0,func) or w.after_idle(func) 
    except StopIteration: 
     return 
func() 

... строки кода будет выводить то же самое.

Смежные вопросы