【问题标题】:error in pyqt qthread not printedpyqt qthread 中的错误未打印
【发布时间】:2014-03-23 04:07:22
【问题描述】:

我无法从 QThread 获取(打印)错误信息。我有一个Worker(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

输出小部件

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)都没有打印错误?我该如何解决这个问题?

【问题讨论】:

标签: python pyqt qthread


【解决方案1】:

您首先需要在您的线程中包含一个包罗万象的异常子句,否则您的异常(来自a 是不存在的全局)将不会被捕获并导致线程和应用程序退出。然后,从这个包罗万象中,您调用sys.exc_info() 以获取回溯信息,并调用sys.excepthook() 获取回溯信息。这会将回溯发送到标准错误(而不是标准输出)。所以试试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,您可以直接捕获,并为真正的异常情况(意外异常)保留包罗万象:

    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...

【讨论】:

  • 感谢您的快速回答。我也在考虑这个方向。添加了sys.stderr 和新方法的行,但问题没有解决。我认为 QThread 在遇到错误时会停止,但没有显示错误消息。我对pyqt(和python)很陌生,我不太明白sys.excepthook 是什么意思。我希望有一些好的技巧,但我现在得到的只是新的未知区域:/.
  • @avstenit 啊,是的,抱歉,现在说得通了,我已经更新了。
  • 感谢@Schollii 提供清晰明确的答案/解决方案 - 它有效。我刚刚意识到,目前我希望(需要)所有输出都将写入 Eclipse 控制台(pydev),因此我不需要输出小部件。我在没有输出小部件的情况下重复了这种情况,以便所有内容都显示在控制台中,但没有显示错误。使用来自QThreadprint 数据显示在控制台中,但是当它应该显示来自线程的错误(或任何错误)时 - 不显示错误。我想问你我应该如何解决这个问题?
  • @avstenit 你能把它作为一个单独的问题发布并提供更多细节吗?
  • 感谢@Schollii 的帮助。我已经解决了。不得不写几行。
猜你喜欢
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
  • 2015-09-08
  • 2014-03-25
  • 2014-09-05
  • 1970-01-01
相关资源
最近更新 更多