据我所知,如果 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"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)