简体   繁体   English

pyqt qthread中的错误未打印

[英]error in pyqt qthread not printed

I have problems with not getting (printing) error informations from QThread. 我没有从QThread获取(打印)错误信息的问题。 I have a Worker (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

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): 如果我只在新文件中运行最后一行( 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 : 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()

I would like to know why the error is not printed in OutputWidget nor in console (using eclipse)? 我想知道为什么错误不会在OutputWidget中打印,也不会在控制台中打印(使用eclipse)? How can I solve the problem? 我该如何解决这个问题?

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. 首先,您需要一个包罗万象的在你的线程例外条款,否则您的异常(从a为不存在全局)将去未捕获并导致线程和应用程序退出。 Then, from that catch-all, you call sys.exc_info() to get traceback info and sys.excepthook() with the traceback info. 然后,从该catch-all,您调用sys.exc_info()以获取回溯信息和sys.excepthook()以及回溯信息。 This will send traceback to stderr (rather than stdout). 这将回溯到stderr(而不是stdout)。 So try for OutputWidget : 所以尝试OutputWidget

def __init__(...):
    ...
    sys.stdout = TextOutputSignal(textWritten=self.normalOutputWritten)
    sys.stderr = TextOutputSignal(textWritten=self.errorOutputWritten)
    ...

def errorOutputWritten(self, text):
    self.normalOutputWritten("*** ERROR: " + text)

and for your worker thread: 并为您的工作线程:

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. 通常,您还需要向主线程发出一些错误状态信号,以便应用程序可以确定要执行的操作:向用户显示网络连接丢失等错误,并且应用程序必须确定是否应退出,保存工作,随你。

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): 请注意,如果您想要直接处理一些特定的异常,例如除以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...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM