pygtk glib.timeout_add (): Как узнать, не уничтожен ли таймер? - PullRequest
4 голосов
/ 24 января 2012

В моем приложении я использую функцию для отображения GtkInfoBars с тайм-аутом (как описано https://stackoverflow.com/a/1309257/406281) благодаря glib.timeout_add_seconds ().

Я понимаю, что glib.timeout_add_seconds () долженустановить функцию, которая будет вызываться через равные промежутки времени, пока указанная функция не вернет значение False.

Я не делаю этого, но все работает, как и ожидалось. Это совершенно просто. Вот мой код:

def infobar(self, message, msgtype=gtk.MESSAGE_INFO, timeout=5):
    bar = gtk.InfoBar()
    bar.set_message_type(msgtype)
    bar.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
    bar.connect("response", lambda *args: bar.hide())
    self.vb2.pack_end(bar, False, False)
    label = gtk.Label()
    label.set_markup(message)
    content = bar.get_content_area()
    content.add(label)
    label.show()
    bar.show()
    if timeout:
        glib.timeout_add_seconds(timeout, bar.hide)

ТАК. Время вопроса. Посмотрите, что я сделал в последней строке. Проще говоря, это нормально? Будет ли тайм-аут уничтожаться после сбоя второго вызова bar.hide ()? Или я накапливаюдополнительные кастрированные таймауты, которые будут активироваться каждые 5 секунд [технически] с использованием ресурсов?


В качестве дополнения:

Если, как я подозреваю, этоплохо, и мне действительно нужно возвращать False, чтобы уничтожить тайм-ауты, мне нужна помощь - я не могу понять, как поиграться с кодом, чтобы удовлетворить следующие условия: мне нужно разрешить несколько информационных баров вt в то же время, когда каждый из них остается подключенным к своему собственному таймеру и сигналу ответа кнопки (как сейчас код) ИЛИ Мне нужен каждый новый информационный бар, чтобы заменить любой предыдущий (я не могу понять,как это сделать, не унаследовав таймер от предыдущего инфо-бара - он становится грязным).

Спасибо за чтение!

Ответы [ 2 ]

6 голосов
/ 24 января 2012

Относительно bar.hide, вызываемого более одного раза, я думаю, что этого не происходит, потому что, насколько я знаю, этого должно быть достаточно, чтобы вернуть значение, которое оценивается как False, а bar.hide возвращает None, чтодолжно быть достаточно.Однако, если вы хотите быть полностью уверенным, вы можете проверить что-то вроде этого:

import gtk, glib

def callback():
    print 'called'

glib.timeout_add_seconds(1, callback)
gtk.main()

В этом примере обратный вызов также возвращает None и вызывается только один раз, как вы можете видеть изoutput to stdout.

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

4 голосов
/ 24 января 2012

Widget.hide всегда возвращает None, что glib.timeout_add_seconds идентично ложному. Таким образом, ваш таймер всегда останавливается после запуска один раз. Есть вероятность, что hide будет вызван дважды (когда пользователь нажмет OK и через 5 секунд), но это нормально. Так что да, ваш код в порядке.

Редактировать: Только что-то понял. Вы создаете новую информационную панель каждый раз, когда функция запускается, а затем только скрываете ее. Вместо использования hide используйте destroy, чтобы он был правильно очищен.

... ИЛИ Мне нужно, чтобы каждый новый инфо-бар заменял любой предыдущий (я не могу понять, как это сделать, не унаследовав таймер от предыдущего инфо-бара - он становится грязным).

Это не слишком сложно; просто используйте ту же информационную панель. Запишите возвращаемое значение glib.timeout_add_seconds, затем при замене содержимого информационной панели убейте предыдущий таймер с помощью glib.source_remove.

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

...