Пишу я на PyQt4 довольно сложную штуку (умолчу какую именно -- это сейчас не имеет значения). И довольно часто сталкиваюсь с ситуацией, когда нужно выполнить небольшую цепь действий по сигналу. Всё Ok, но писать для этого функцию типа:
class c(QObject):
...
def __init__(self...):
...
self.connect(self, SIGNAL("signal()", self._signal_func)
...
def _signal_func(self):
work1()
work2()
work3()Неудобно, блин.Такой вариант не катит:
class c(QObject):
...
def __init__(self...):
...
def signal_func():
work1()
work2()
work3()
self.connect(self, SIGNAL("signal()", signal_func)
....Потому, что после выполнения главной функции (в данном случае __init__) вызывается деструктор signal_func (по довольно странным причинам, ведь в QMetaObject должна была остоваться ссылка... ну да ладно.) и, соответственно, disconnect.Можно, конечно, сделать так:
self.connect(self, SIGNAL("signal()", work1)
self.connect(self, SIGNAL("signal()", work2)
self.connect(self, SIGNAL("signal()", work3)Но тогда нам приходится учитывать разные нитивые коллизии. Это не решение.Я нашёл очень своеобразный и спорный выриант (уже не помню где, не сам ли? А может и в доках проскочило... не важно.):
class c(QObject):
...
def __init__(self...):
...
self.connect(self, SIGNAL("signal()", lambda self: work1() or work2() or work3())
....Проще? ИМХО да. Сначала не очень понятно...И, как по какой-то магии, деструктор для лямбды не вызывается. Кто знает почему? Я не нашёл решение (впрочем не особо-то и искал... но искал.).
Нужно только знать вывод work'ов (в данном случае у нас все выводят False), и всегда можно составить то, что нужно.
Например, если work2() вернёт True, то нужно, всего-лишь добавить not...
Если у нас неизвестен вывод work2() (1 и 2 == False), то как вам такое решение?:
lambda self: ((work1() or work2()) and work3()) or work3()Вообще, это называется функциональным программированием... Но это не статья...Если нужно выполнить что-нить вроде self.var = val (в лямбде этого нельзя), то setattr(self, "var", val) замечательно справится... Также неплохо работают globals() и locals() (setdefault).
Меня интересует, это только я такой долблнутый на всю бошку, или есть более нормальные решения?
P.S. Интересно, а сколько человек, увидев тему подумали про Half-Life?
-- Я -- часть той силы, что вечно хочет зла
и вечно совершает благо.