我有一个显示一些小部件和按钮的 PyQt 程序。
我希望程序可以作为独立的 python 实例运行,也可以在 ipython 环境中运行。在这种情况下,我在 Jupyter 控制台中使用以下魔法命令(以前我在启动 ipython qtconsole 时必须使用 --gui=qt)
%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(请参阅防止 PyQt 使插槽中发生的异常静音):不起作用,因为 ipython 不断覆盖 sys.excepthook
- 检测 IPython 是否正在运行,然后使用 IPYTHON.set_custom_exc(在任何(未捕获的)异常上打开 IPython shell):不幸的是,qt 事件循环异常不会触发处理程序。
- 覆盖 QApplication.notify:运气不好,我打算在派生函数中调用的原生 QApplication.notify 函数没有抛出异常,返回值(布尔值)也没有反映插槽的正确执行。这个线程中的答案很有趣:如何记录 QApplication 的未捕获异常?但是,这种策略似乎在 Qt c++ 中有效,但是 notify 的 python 包装器只是将异常打印到控制台而不是引发它们。
这是一个困扰我很久的问题。有没有人有办法解决吗?