Exception handling PyQt事件处理程序snarf异常
下面是说明问题的代码:Exception handling PyQt事件处理程序snarf异常,exception-handling,pyqt,pyqt4,Exception Handling,Pyqt,Pyqt4,下面是说明问题的代码: from PyQt4 import QtGui app = QtGui.QApplication([]) dialog = QtGui.QDialog() button = QtGui.QPushButton('I crash') layout = QtGui.QHBoxLayout() layout.addWidget(button) dialog.setLayout(layout) def crash(): raise Exception('Crash!') butt
from PyQt4 import QtGui
app = QtGui.QApplication([])
dialog = QtGui.QDialog()
button = QtGui.QPushButton('I crash')
layout = QtGui.QHBoxLayout()
layout.addWidget(button)
dialog.setLayout(layout)
def crash(): raise Exception('Crash!')
button.clicked.connect(crash)
button.click()
print 'I should not happen'
当我运行它时,PyQt4为我处理错误。我的控制台显示带有“崩溃”的堆栈跟踪等等,我看到‘我不应该发生’
这是没有用的,因为我已经收到了一个包含许多处理程序的大型应用程序,我需要将它们的所有错误强制到我的脸上(以及我的自动化测试中)。每次我运行时,错误都会从我的网络中逃逸出来,它们需要大量无用的尝试:除了块,在每个处理程序中,只是为了捕捉它们
换句话说,我希望好代码非常好,坏代码非常坏。没有粉饰
如果已经有人问过,我会道歉,但当我在网上搜索时,我自然会有成千上万的新手问一些基本的错误处理问题(或者,更糟糕的是,我会有新手问如何关闭他们任性的异常!)
如何覆盖PyQt4的默认错误处理,以便自己传播或记录错误?请不要回答Sy.例外,也就是说,它捕获了PyQT4没有捕获的错误。 < P>我认为答案不是“代码”> PyQt < /COD>,而是设计让信号/时隙工作的固有后果(记住信号/时隙通信也通过C++层)。 这很难看,但是否有一点和结束运行围绕你的问题
from PyQt4 import QtGui
import time
app = QtGui.QApplication([])
class exception_munger(object):
def __init__(self):
self.flag = True
self.txt = ''
self.type = None
def indicate_fail(self,etype=None, txt=None):
self.flag = False
if txt is not None:
self.txt = txt
self.type = etype
def reset(self):
tmp_txt = self.txt
tmp_type = self.type
tmp_flag = self.flag
self.flag = True
self.txt = ''
self.type = None
return tmp_flag, tmp_type, tmp_txt
class e_manager():
def __init__(self):
self.old_hook = None
def __enter__(self):
em = exception_munger()
def my_hook(type, value, tback):
em.indicate_fail(type, value)
sys.__excepthook__(type, value, tback)
self.old_hook = sys.excepthook
sys.excepthook = my_hook
self.em = em
return self
def __exit__(self,*args,**kwargs):
sys.excepthook = self.old_hook
def mang_fac():
return e_manager()
def assert_dec(original_fun):
def new_fun(*args,**kwargs):
with mang_fac() as mf:
res = original_fun(*args, **kwargs)
flag, etype, txt = mf.em.reset()
if not flag:
raise etype(txt)
return res
return new_fun
@assert_dec
def my_test_fun():
dialog = QtGui.QDialog()
button = QtGui.QPushButton('I crash')
layout = QtGui.QHBoxLayout()
layout.addWidget(button)
dialog.setLayout(layout)
def crash():
time.sleep(1)
raise Exception('Crash!')
button.clicked.connect(crash)
button.click()
my_test_fun()
print 'should not happen'
这不会打印“不应该发生”,并为您的自动测试提供一些信息(使用正确的异常类型)
[11]中的:回溯(最近一次调用):
文件“/tmp/ipython2-3426rwB.py”,第68行,在崩溃中
例外:崩溃!
---------------------------------------------------------------------------
异常回溯(最后一次最近调用)
在()
---->1个execfile(r'/tmp/ipython2-3426rwB.py')#PYTHON-MODE
/tmp/ipython2-3426rwB.py英寸()
/tmp/ipython2-3426rwB.py在新_fun(*args,**kwargs)
例外:崩溃!
在[12]中:
堆栈跟踪被顶起,但您仍然可以读取打印出来的第一个堆栈跟踪。这不是答案,您这个愚蠢的网站。不要强迫我们去适应一个理想化线程模板的先入为主的概念 解决方法是使用my test framework setUp()挂接异常处理程序:
def setUp(self):
self.no_exceptions = True
def testExceptionHook(type, value, tback):
self.no_exceptions = False
sys.__excepthook__(type, value, tback)
sys.excepthook = testExceptionHook
如果说“self.no_exceptions=False”,我宁愿简单地说self.fail(“”)。然而,因为Python的单元测试库坚持抛出异常只是为了注册测试失败,而且因为PyQt坚持捕捉所有异常,所以我们出现了死锁
为了适应unittest.TestCase对理想化测试用例的愚蠢先入为主的概念,我必须设置一个变量,然后在拆卸中检测它:
def tearDown(self):
self.assertTrue(self.no_exceptions)
这仍然不理想,但至少会迫使我花更多的时间关注错误,而不是花时间在技术网站上抱怨错误
根本问题:如何关闭PyQt的神奇错误处理程序仍然没有回答…我想你的问题是异常发生在
PyQt
事件循环运行的地方(我认为这是另一个线程),所以你真的在问如何在线程之间移动异常。sry no-我发布的代码已经完成。没有MainLoop事件调度器;我只是直接调用.click()。即使它没有使用多个线程,它仍然在运行事件循环机制(可以将函数执行移动到不同的线程),因此我认为问题仍然是在线程之间移动异常,只是源和目标是相同的。您是否尝试过sys.excepthook
?它将捕获该异常。print threading.currentThread()在.click()之前和def crash()内部返回相同的对象。(而且,一般来说,窗口架构是单线程的&事件驱动的。)tx-I确实使用sys.excepthook是错误的。然而。。。无论我在钩子里写了什么,我似乎都无法脱离事件处理程序。我必须放弃我的目标,写一个程序,如果它有一个未处理的异常就会死掉。我必须将我的目标降低到只在测试框架中充分捕获异常。因为测试已经有了一个框架,我不需要你的包装器。。。但是根本问题仍然没有答案——如何关闭这个PyQt特性。
def tearDown(self):
self.assertTrue(self.no_exceptions)