当前位置: 首页 > 面试题库 >

防止PyQt沉默插槽中发生的异常

穆锋
2023-03-14
问题内容

据我所知,如果在PyQt下的插槽中发生异常,该异常会打印到屏幕上,但不会冒泡。这在我的测试策略中造成了一个问题,因为如果插槽中发生异常,我将不会看到测试失败。

这是一个例子:

import sys
from PyQt4 import QtGui, QtCore

class Test(QtGui.QPushButton):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setText("hello")
        self.connect(self, QtCore.SIGNAL("clicked()"), self.buttonClicked)

    def buttonClicked(self):
        print "clicked"
        raise Exception("wow")

app=QtGui.QApplication(sys.argv)
t=Test()
t.show()
try:
    app.exec_()
except:
    print "exiting"

请注意,异常永远不会退出程序。

有没有解决此问题的方法?


问题答案:

可以创建一个包装PyQt的新信号/插槽装饰器的装饰器,并为所有插槽提供异常处理。也可以重写QApplication :: notify来捕获未捕获的C
++异常。

import sys
import traceback
import types
from functools import wraps
from PyQt4 import QtGui, QtCore

def MyPyQtSlot(*args):
    if len(args) == 0 or isinstance(args[0], types.FunctionType):
        args = []
    @QtCore.pyqtSlot(*args)
    def slotdecorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                func(*args)
            except:
                print "Uncaught Exception in slot"
                traceback.print_exc()
        return wrapper

    return slotdecorator

class Test(QtGui.QPushButton):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setText("hello")
        self.clicked.connect(self.buttonClicked)

    @MyPyQtSlot("bool")
    def buttonClicked(self, checked):
        print "clicked"
        raise Exception("wow")

class MyApp(QtGui.QApplication):
    def notify(self, obj, event):
        isex = False
        try:
            return QtGui.QApplication.notify(self, obj, event)
        except Exception:
            isex = True
            print "Unexpected Error"
            print traceback.format_exception(*sys.exc_info())
            return False
        finally:
            if isex:
                self.quit()

app = MyApp(sys.argv)

t=Test()
t.show()
try:
    app.exec_()
except:
    print "exiting"


 类似资料:
  • 我试图将JSF2.2与bootstrap 3.2.0组件结合起来,但在尝试使用带有动态生成的标签列表的按钮组时遇到了问题。我将问题追溯到ui:repeat标记包含在生成的html中,从而阻止了引导程序的正确css样式。 更新只是为了好奇,按钮被显示为普通按钮(在它们之间有间距),而不是在组按钮全部在一起样式中所希望的。

  • 我们的编写器设计用于将记录写入关系数据库。如果任何记录发生异常,Spring Batch将对区块中的每条记录执行回滚并重试写入操作。这导致发生SQL重复密钥异常,因为区块中先前处理的记录已成功写入数据库。 我们已经尝试使用noRetry()和noRollback(),明确指定不应该触发重试或回滚的异常列表。 根据Spring Batch在线留档noRollback()可用于防止在ItemWrite

  • 问题内容: 我有一个任务栏菜单,单击该任务栏菜单将其连接到获取触发事件的插槽。现在的问题是,我想知道单击了哪个菜单项,但是我不知道如何将该信息发送到连接的功能。这是用于将操作连接到功能的代码: 我知道有些事件会返回一个值,但是Trigger()不会。那么我该如何实现呢?我必须发出自己的信号吗? 问题答案: 用一个 这是PyQt书中的一个示例: 顺便说一句,您也可以使用,但是我发现该方法更加简单明了

  • 问题内容: 我想知道其他SOer在实践中如何倾向于处理和/或防止异常。 您在什么情况下可以防止例外情况,以及如何防止例外情况?在什么情况下您会捕获异常? 通常,我通常会说“ NullPointerExceptions”(和其他类似的事件) 我发现在大多数情况下,这比使用try-catch块所涉及的所有事情要小。 当潜在异常更复杂或数量更多时,我使用try-catch块。 问题答案: 我认为,仅当引

  • 问题内容: 我无法避免在RuntimeException之后阻止事务回滚。我的环境是在Websphere 8.0上运行的Spring 4.1 + Hibernate 3.6 + JTA(WebSphereUowTransactionManager)。 首先,一个简单的情况表现出预期的效果。由于我 捕获了RuntimeException ,因此事务提交并成功创建了新资源。 下一个也可以。我声明了 n

  • 本文向大家介绍vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】,包括了vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了vue 使用插槽分发内容操作。分享给大家供大家参考,具体如下: 单个插槽 除非子组件模板包含至少一个 <slot> 插口,否则父组件的内容将会被丢弃。当子组件模板只有一个没有属性的插槽时,父