2016-11-15 3 views
3

У меня есть программа PyQt, в которой отображаются некоторые виджеты и кнопки.Исключения в петле событий PyQt и ipython

Я хочу, чтобы программа запускалась либо как отдельный экземпляр python, либо внутри среды ipython. В этом случае я использую следующую команду в волшебную Jupyter консоли (ранее я должен был использовать --gui = Qt при запуске IPython qtconsole)

%pylab qt 

Для того, чтобы иметь программу, которая работает в обоих направлениях, моя главная модуль имеет следующие строки:

APP = QtGui.Qapplication.instance() # retrieves the ipython qt application if any 
if APP is None: 
    APP = QtGui.QApplication(["foo"]) # create one if standalone execution 

if __name__=='__main__': 
    APP.exec_() # Launch the event loop here in standalone mode 

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

Я попробовал несколько стратегий, но там, кажется, заговор между PyQt и внутренними механизмами IPython, чтобы сделать это невозможно:

  • переописать sys.excepthook (см Preventing PyQt to silence exceptions occurring in slots): не работает, потому что IPython держит overwritting SYS .excepthook
  • Обнаружение при запуске IPython, а затем использование IPYTHON.set_custom_exc (Opening an IPython shell on any (uncatched) exception): К сожалению, исключения цикла событий qt не запускают обработчик.
  • Перезаписать QApplication.notify: неудача, встроенная функция QApplication.notify, которую я намереваюсь вызывать в производной функции, не выбрасывает исключения, равно как и возвращаемое значение (логическое) отражает правильное выполнение слотов. Ответ в этой теме интересен: How to log uncatched exceptions of a QApplication?, однако, похоже, что эта стратегия работает в Qt C++, но оболочка python извещения просто печатает исключения на консоли, а не поднимает их.

Это проблема, которая беспокоит меня с давних времен. у кого-нибудь есть решение?

+0

Попробуйте решение, предложенное в [этом ответе] (http://stackoverflow.com/a/28758396/984421). – ekhumoro

+0

Я забыл об этом: перезаписывая функцию, которую IPython будет использовать в качестве патча обезьяны для sys.excepthook (как предложено в вашем ответе) тоже не работает.Фактически, Ipython с опцией qt предотвратит цикл цикла qt даже от вызова sys.excepthook. Я не понимаю, какие разработчики IPython находят настолько непристойными в исключениях цикла catching!! – Samuel

+0

Честно говоря, я думаю, что это пустая трата времени, сообщающая все это здесь: вам нужно взять это с помощью разработчиков ipython. – ekhumoro

ответ

4

На самом деле, ответ разработчика указал мне в правильном направлении: проблема в том, что каждый раз, когда выполняется ipython-ячейка, новый sys.excepthook обезврежен обезьян, после выполнения выполнения sys.excepthook возвращается к предыдущему (см. ipkernel/kernelapp.py).

Из-за этого изменение sys.excepthook в обычной инструкции ячейки ipython не будет изменять excepthook, которая выполняется во время цикла событий qt.

Простое решение заключается в monkeypatch sys.excepthook внутри кварт события:

from PyQt4 import QtCore, QtGui 
import sys 
from traceback import format_exception 

def new_except_hook(etype, evalue, tb): 
    QtGui.QMessageBox.information(None, 
            str('error'), 
            ''.join(format_exception(etype, evalue, tb))) 

def patch_excepthook(): 
    sys.excepthook = new_except_hook 
TIMER = QtCore.QTimer() 
TIMER.setSingleShot(True) 
TIMER.timeout.connect(patch_excepthook) 
TIMER.start() 

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

Я думаю, можно предположить, что обезьяна заплатит другую версию new_except_hook в зависимости от того, какой виджет запускает исключение, вызвав patch_excepthook внутри event_handler каждого виджета.

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

  • Нет связанных вопросов^_^