Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 17, 2012 13:34:09

Serbis
От:
Зарегистрирован: 2012-02-13
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

RuntimeError: maximum recursion depth exceeded

Вопрос конечно немного не сюда, он скорее относится к теме QT, но имеет несколько промежуточный характер, поэтому я опубликую его здесь. Значит в чем суть. Имеется таблица, с обработчиком(слотом) события(сигнала), изменения содержимого ячейки. Смысл обработчика таков - проверить совершен ли ввод в ячейку соответствующей строки, и если да, то дополнить не введенные нули. Суть в чем, все работает как нужно, за одним моментом - происходит RuntimeError, но не приводивший до поры до времени к крешу программы, теперь приводит. Вообще, если я правильно понял суть, происходит превышение лимита обработки прерывания от клавиатуры. Так как опытным путем удалось выяснить что slot_cellChange вызывается 1000 раз, на 1001 происходит сбой. Но как с этим бороться не имею представления.

  self.connect(self.table, QtCore.SIGNAL('cellChanged (int, int)'), lambda row = 1:				                             self.slot_cellChange(row))
def slot_cellChange(self, row):
    lit = self.field[row]
    if lit == 'Stock':
      it = self.table.item(row, 1)
      self.table.setItem(row, 1, QtGui.QTableWidgetItem(format(float(str(it.text())), ".3f")))

Вывод:


Traceback (most recent call last):
File “/home/serbis/Prog/python/b3/sources/createa/table.py”, line 28, in <lambda>
self.connect(self.table, QtCore.SIGNAL('cellChanged (int, int)'), lambda row = 1: self.slot_cellChange(row))
RuntimeError
Error in sys.excepthook:
Traceback (most recent call last):
File “/usr/lib/python2.6/dist-packages/apport_python_hook.py”, line 44, in apport_excepthook
if exc_type in (KeyboardInterrupt, ):
RuntimeError: maximum recursion depth exceeded in cmp

Original exception was:
Traceback (most recent call last):
File “/home/serbis/Prog/python/b3/sources/createa/table.py”, line 28, in <lambda>
self.connect(self.table, QtCore.SIGNAL('cellChanged (int, int)'), lambda row = 1: self.slot_cellChange(row))
RuntimeError: maximum recursion depth exceeded



Офлайн

#2 Июнь 17, 2012 13:44:32

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

RuntimeError: maximum recursion depth exceeded

Как насчет использования поисковика? Вбиваете ошибку - ‘maximum recursion depth exceeded’ - на первой странице полно ответов.

Вкратце для лентяев: меняйте логику или поставьте sys.setrecursionlimit повыше.

RuntimeError: maximum recursion depth exceeded in cmp
происходит превышение лимита обработки прерывания от клавиатуры
Надо бы подучить основы программирования и английский.



Отредактировано fata1ex (Июнь 17, 2012 13:57:07)

Офлайн

#3 Июнь 17, 2012 13:53:20

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

RuntimeError: maximum recursion depth exceeded

Serbis
Вообще, если я правильно понял суть, происходит превышение лимита обработки прерывания от клавиатуры.
Причина не в этом.

RuntimeError: maximum recursion depth exceeded
Это значит, что превышен лимит рекурсии, т.е. функция вызывает сама себя много раз:
def foo():
    foo()
foo()

В вашем случае это вызвано тем, что в обработчике сигнала cellChanged вызывается setItem, который порождает сигнал cellChanged. От того рекурсия и получается.

Решение - временно блокировать сигналы:
self.table.blockSignals(True)
# do something with table, like setItem
self.table.setItem(...)
self.table.blockSignals(False)

Для надежности, можно обернуть это в try, finally.

Хотя, лучше бы было проверять в обработчике какие-то условия, типа номера столбца и т.п., чтобы не допустить рекурсии.

Отредактировано reclosedev (Июнь 17, 2012 14:00:23)

Офлайн

#4 Июнь 17, 2012 16:16:33

Serbis
От:
Зарегистрирован: 2012-02-13
Сообщения: 38
Репутация: +  0  -
Профиль   Отправить e-mail  

RuntimeError: maximum recursion depth exceeded

Спасибо, про рекурсию я понял почти сразу, а вот про то что можно сигналы от объектов блокировать, вот за это спасибо



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version