Я хочу ограничить частоту выполнения обратного вызова Tkinter - PullRequest
1 голос
/ 13 июля 2010

Я пишу свою первую программу с графическим интерфейсом для Tkinter (на самом деле, первую программу на Python).

У меня есть виджет Entry для поиска, и результаты переходят в список. Я хочу, чтобы результаты обновлялись как пользовательские типы, поэтому я сделал обратный вызов следующим образом:

search_field.bind("<KeyRelease>", update_results)

Проблема в том, что поиск обновляется много раз подряд. Поскольку результаты будут поступать из запроса к базе данных, это генерирует много ненужного трафика. То, что я действительно хочу, чтобы это обновлялось каждую секунду или около того, или подождать секунду после того, как пользователь перестанет печатать, а затем выполнить поиск. Какой самый простой способ сделать это? Спасибо

ОБНОВЛЕНИЕ: Это прекрасно работает для того, что я описал, но теперь я понял, что мне также нужно запустить обновление после того, как пользователь перестанет печатать. В противном случае последние несколько символов никогда не включаются в поиск. Я думаю, что я должен принять ответ, чтобы вернуться в список вопросов ...

Ответы [ 2 ]

2 голосов
/ 13 июля 2010

Хороший способ сделать это - простой кеширующий декоратор:

import time
def limit_rate( delay=1.0 ):
    """ produces a decorator that will call a function only once per `delay` """
    def wrapper( func ): # the actual decorator
        cache = dict( next = 0 ) # cache the result and time
        def limited( *args, **kwargs):
            if time.time() > cache['next']: # is it time to call again
                cache['result'] = func( *args, **kwargs) # do the function
                cache['next'] = time.time() + delay # dont call before this time
            return cache['result']
        return limited
    return wrapper

Он работает так:

@limit_rate(1.5)
def test():
    print "Called test()"
    time.sleep( 1 )
    return int(time.time())

print [test() for _ in range(5)] # test is called just once

Вы просто добавили бы этот декоратор куда-нибудь и украсили бы свой update_results функция с ним.

0 голосов
/ 14 июля 2010

Разобрался.Я вызываю декорированную функцию с задержкой, используя any_widget.after (delay_in_ms, function).

...