2015-08-18 2 views
1

Моя программа выполняет сложные вычисления, которые продолжаются около 30 минут. Я хотел бы быть обновлен о значениях некоторых переменных в графическом интерфейсе Tkinter с идеально определенными переменными, связанными с определенными метками, чтобы они обновлялись автоматически, когда они меняли свои значения. Хотя я понимаю, что могу создать 2 потока (один для основной программы и один для TKinter, который вызывает себя каждую секунду или около того), мне интересно, есть ли более элегантный способ справиться с этим. Любые предложения приветствуются.Обновление метки фона на основе событий Tkinter

В приведенном ниже примере показано, как это может выглядеть, но пример не работает.

import Tkinter as tk 
import time 

class SampleApp(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 

     self.counter = tk.Label(self, text="") 
     self.counter.pack() 

     # start the clock "ticking" 
     self.mainLoop() 

    def mainLoop(self): 
     for i in range (10000): 
      j=i^2 
      self.counter.configure(text=str(j)) 
      time.sleep(0.1) 

if __name__== "__main__": 
    app = SampleApp() 
    app.mainloop() 

Однако, он работает, когда MainLoop заменяется следующим образом:

def mainLoop(self): 
    now = time.strftime("%H:%M:%S" , time.gmtime()) 
    self.counter.configure(text=now) 
    # call this function again in one second 
    self.after(1000, self.mainLoop) 

Мои вопросы:

  1. Почему работать с "self.after", но не с for loop
  2. Есть ли более элегантный способ обновления меток, управляемых событиями (не на основе кнопки, а при вычислении, который изменяет определенные переменные)
+0

Вы пытались использовать Google для таких терминов, как «python tkinter after sleep»? – TigerhawkT3

ответ

0

Чтобы ответить на первый вопрос -

Почему работать с «self.after», но не с петлей для

__init__() метод класса вызывается, когда объект этот класс в созданном. Теперь в вашем случае класс будет создаваться в соответствии -

app = SampleApp() 

И в вашем __init__(), вы звоните - self.mainLoop().

В корпусе петли for все это работает в основном потоке. И так он не вернется с self.mainLoop() до тех пор, пока он не будет завершен, так как вы не начинаете self.mainLoop() как отдельный поток, вы делаете это в том же потоке. Следовательно, управление достигнет линии root.mainloop() только после того, как self.mainLoop() `завершит и вернет элемент управления обратно.


В случае использования after() метода, он ведет себя что-то, как он регистрирует событие будет уволено после того, как некоторое количество времени, и немедленно возвращается, она не ожидает, что много количества времени, и ни для функции вернуться. Следовательно, управление немедленно возвращается, и он вызывает root.mainloop(), чтобы показать графический интерфейс.

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