我没有从QThread获取(打印)错误信息的问题。我有工作人员(QThread):
class Worker(QThread):
def __init__(self, parent=None):
QThread.__init__(self, parent)
def run(self):
# do some heavy work here
print 1 # 1 is printed in my OutputWidget
print a # a is not defined and it should print an error
如果我只在新文件中运行最后一行(print a
)(其中未定义a
),我会收到错误(这是正确的和预期的):
Traceback (most recent call last):
File "C:\...\output_widget\output_from_qthread_V2.py", line 1, in run
print a
NameError: global name 'a' is not defined
OutputWidget :
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
from output_widget_ui import Ui_Form
class TextOutputSignal(QtCore.QObject):
textWritten = QtCore.pyqtSignal(str)
def write(self, text):
self.textWritten.emit(str(text))
class OutputWidget(QtGui.QWidget):
def __init__(self, parent=None, flags=0):
super(OutputWidget, self).__init__(parent)
sys.stdout = TextOutputSignal(textWritten=self.normalOutputWritten)
self.ui = Ui_Form()
self.ui.setupUi(self)
def __del__(self):
# Restore sys.stdout
sys.stdout = sys.__stdout__
def normalOutputWritten(self, text):
cursor = self.ui.textOutputWidget.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(text)
self.ui.textOutputWidget.ensureCursorVisible()
我想知道为什么错误不会打印在 OutputWidget 中,也不会打印在控制台中(使用eclipse)?我该如何解决这个问题呢?
答案 0 :(得分:3)
您首先需要在您的线程中使用catch-all exception子句,否则您的异常(来自a
不存在的全局)将被删除并导致线程和应用程序退出。然后,从那个全能,您调用sys.exc_info()
获取追溯信息,并使用追溯信息调用sys.excepthook()
。这将回溯到stderr(而不是stdout)。所以试试OutputWidget
:
def __init__(...):
...
sys.stdout = TextOutputSignal(textWritten=self.normalOutputWritten)
sys.stderr = TextOutputSignal(textWritten=self.errorOutputWritten)
...
def errorOutputWritten(self, text):
self.normalOutputWritten("*** ERROR: " + text)
和你的工作线程:
class Worker(QThread):
...
def run(self):
try:
# do some heavy work here
print 1 # 1 is printed in my OutputWidget
print a # a is not defined and it should print an error
except:
(type, value, traceback) = sys.exc_info()
sys.excepthook(type, value, traceback)
...decide if should exit thread or what...
在上面,异常将导致线程正常退出,您将在控制台中看到错误。通常,您还需要向主线程发出一些错误状态信号,以便应用程序可以确定要执行的操作:向用户显示网络连接丢失等错误,并且应用程序必须确定是否应退出,保存工作,随你。
请注意,如果您想要直接处理一些特定的异常,例如除以0或NameError
,则直接捕获,并保留catch-all以获得真正异常的条件(意外异常):
def run(self):
try:
# do some heavy work here
print 1 # 1 is printed in my OutputWidget
print a # a is not defined and it should print an error
except NameError, exc:
sys.stderr.write( "Name Error\n" );
...decide if should exit thread or what...
except:
(type, value, traceback) = sys.exc_info()
sys.excepthook(type, value, traceback)
...decide if should exit thread or what...