2013-08-30 3 views
1

У меня есть следующий код:питона, показывающий текущее состояние кода

from Tkinter import * 

root = Tk() 

def count(): 
    for i in range(300): 
     Display.configure(text = 'The current number is: '+str(i)) 

Button = Button(root, text = 'Start', command = count) 
Button.pack() 

Display = Label(root) 
Display.pack() 

root.mainloop() 

Я хочу это, что после нажатия кнопки «Пуск», чтобы отобразить текущее число во время подсчета, но это не будет работать. Он отображает только номер после завершения подсчета, поэтому после подсчета только показывает: «Текущее число: 299». (Дело в том, что я хочу знать, как отображать текущее состояние кода. (Мне нужно создать приложение, которое собирает определенные файлы, чем копирует его в определенные места, и я хочу, чтобы он отображал, какой файл он в настоящее время выполняется копирование.Приложение работает с работами за исключением отображения текущего файла.Я попытался проверить отображение с помощью кода выше.)

ответ

1

В вашем примере кода проблема в том, что, прежде всего, дисплей не имеет никаких изменений для обновления внутри вашего цикла, и, во-вторых, если бы он обновлялся, было бы быстро увидеть любой другой номер, чем последний.

Простым решением является вызов root.update_idletasks(), чтобы отобразить изменение для обновления

from Tkinter import * 
import time 

root = Tk() 

def count(): 
    for i in range(300): 
     Display.configure(text = 'The current number is: '+str(i)) 
     root.update_idletasks() 
     time.sleep(0.01) # just to see something 

Button = Button(root, text = 'Start', command = count) 
Button.pack() 

Display = Label(root) 
Display.pack() 

root.mainloop() 

, вероятно, лучше всего использовать сопрограмму (который я завернутую в декоратор здесь) и after_idle:

import time 
from Tkinter import * 

root = Tk() 

def updatesdisplay(func): 
    def driver(iterator): 
     try: next(iterator) 
     except StopIteration: pass 
     else: root.after_idle(driver, iterator) 
    def wrapped(): 
     driver(func()) 
    return wrapped 

@updatesdisplay 
def count(): 
    for i in range(300): 
     time.sleep(0.005) # just to see something 
     Display.configure(text = 'The current number is: '+str(i)) 
     yield # chance to update display here 

Button = Button(root, text = 'Start', command = count) 
Button.pack() 

Display = Label(root) 
Display.pack() 

root.mainloop() 
+0

Спасибо, это именно то, что я искал! Одна из незначительных вещей: если я использую метод Display.place() и перебираю список, содержащий строки (длина строки может меняться в диапазоне от 24 до 65), при отображении текста, который он перескакивает слева направо правильно. Если я модифицирую код таким образом, что пользователь должен щелкнуть по кнопке, тогда он отобразит следующий элемент в списке, текст останется статичным (поэтому он работает так, как я хочу). Есть ли решение для этого? – user2665140

+0

@ user2665140 Наверное, трудно сказать, не видя примера. Возможно, просто опубликуйте новый вопрос с кодом, который воспроизводит проблему. – sloth