【发布时间】:2017-03-29 06:18:39
【问题描述】:
我有一个显示一些小部件和按钮的 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(请参阅 Preventing PyQt to silence exceptions occurring in slots):由于 ipython 不断覆盖 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++ 中有效,但是 notify 的 python 包装器只是将异常打印到控制台而不是引发它们。
这是一个困扰我很久的问题。有人有解决办法吗?
【问题讨论】:
-
尝试this answer中建议的解决方案。
-
我忘记了这一点:覆盖 IPython 将用作 sys.excepthook 的猴子补丁的函数(如您的回答中所建议的那样)也不起作用。事实上,带有 qt 选项的 Ipython 甚至会阻止 qt 事件循环调用 sys.excepthook。我不明白 IPython 开发人员在捕获事件循环异常时发现了什么如此淫秽?!
-
老实说,我认为在这里报告所有这些是浪费时间:您需要与 ipython 开发人员一起讨论。
-
谢谢,我在 ipython 的 github issue 页面发帖:github.com/ipython/ipython/issues/10057。与此同时,我也注意到了这个相关的问题。 stackoverflow.com/questions/26426419/….
标签: python qt ipython pyqt4 qtconsole