我有一个显示一些小部件和按钮的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函数不会抛出异常,返回值(boolean)也不会反映插槽的正确执行。在这个线程中的答案很有趣:How to log uncatched exceptions of a QApplication?,但是,似乎这种策略在Qt C++中起作用,但是通知的python包装只是向控制台输出异常而不是提升它们。
这是一个长期以来一直困扰着我的问题。有没有人有办法解决吗?
尝试在[此答案]中建议的解决方案(http://stackoverflow.com/a/28758396/984421)。 – ekhumoro
我忘了这个:覆盖IPython将用作sys的猴子补丁的函数。excepthook(正如您的答案中所建议的)也不起作用。实际上,带有qt选项的Ipython将阻止qt事件循环甚至调用sys.excepthook。我不明白IPython开发人员在捕获事件循环异常时发现如此猥亵?! – Samuel
老实说,我认为这里报告所有这些都是浪费时间:你需要把它与ipython开发者结合起来。 – ekhumoro