pyqt qthread 中的错误未打印 [英] error in pyqt qthread not printed

查看:61
本文介绍了pyqt qthread 中的错误未打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法从 QThread 获取(打印)错误信息.我有一个 Worker (QThread):

I have problems with not getting (printing) error informations from QThread. I have a 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 未定义),我会收到一个错误(这是正确的和预期的):

If I run only the last line (print a) in new file (where a is not defined) I get an error (which is correct and expected):

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

I would like to know why the error is not printed in OutputWidget nor in console (using eclipse)? How can I solve the problem?

推荐答案

你首先需要在你的线程中使用一个包罗万象的异常子句,否则你的异常(来自 a 是不存在的全局)将未被发现并导致线程和应用程序退出.然后,从这个包罗万象中,您调用 sys.exc_info() 以获取回溯信息和带有回溯信息的 sys.excepthook() .这会将回溯发送到 stderr(而不是 stdout).所以试试 OutputWidget:

You first need a catch-all exception clause in your thread, otherwise your exception (from a being non-existent global) will go uncaught and cause thread and app exit. Then, from that catch-all, you call sys.exc_info() to get traceback info and sys.excepthook() with the traceback info. This will send traceback to stderr (rather than stdout). So try for 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...

在上面,异常会导致线程正常退出,你会在控制台看到一个错误.通常,您还需要向主线程发出一些错误状态的信号,以便应用程序可以确定要做什么:向用户显示网络连接丢失等错误,并且应用程序必须决定是否应该退出,保存工作,任何.

In the above, the exception will cause thread to exit gracefully and you will see an error in console. In general, you will want to signal the main thread some error status too so that the application can determine what to do: show the user an error that network connectivity was lost, etc, and app must decide if it should exit, save work, whatever.

请注意,如果您有几个要直接处理的特定异常,例如除以 0 或 NameError,您可以直接捕获,并保留所有真正异常情况(意外例外):

Note that if you have a couple specific exceptions that you want to deal with directly, like division by 0 or NameError, you trap directly, and keep the catch-all for truely exceptional conditions (unexpected exceptions):

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

这篇关于pyqt qthread 中的错误未打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆