PyQt5 重定向输出以及错误信息

        最近用PyQt5写一个耗时比较长的计算程序,需要把控制台的信息(包括正常输出和报错)打印到界面上,方便观察计算的进度。在网上找了很多资料,都比较散乱,现在把我的经验记录下来。

        先上完整的程序,可以实现重定向输出以及错误信息的功能。

# -*- coding: utf-8 -*-、

import sys

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import QWidget, QApplication

class Stream(QObject):
    """【输出重定向】重定向控制台输出到文本框控件"""
    newText = pyqtSignal(str)
    # 任何定义了类似于文件write方法的对象可以指定给sys.stdout,所有的标准输出将发送到该方法对象上
    def write(self, text):
        self.newText.emit(str(text))
        QApplication.processEvents()

class Ui_Form(QWidget):
    """主界面"""
    def __init__(self):
        super().__init__()

        # 【输出重定向】自定义输出流
        # sys.stdout = Stream(newText=self.onUpdateText)
        sys.stdout = Stream()
        sys.stdout.newText.connect(self.onUpdateText)

        self.resize(500, 500)
        self.textEdit = QtWidgets.QTextEdit(self)
        self.QPushButton = QtWidgets.QPushButton('点我生成错误',self)
        self.QPushButton.clicked.connect(self.createrro)
        self.QPushButton.move(300,300)

    def closeEvent(self, event):
        """【输出重定向】重写closeEvent,程序结束时将stdout恢复默认"""
        sys.stdout = sys.__stdout__
        super().closeEvent(event)

    def onUpdateText(self, text):
        """【输出重定向】重定向控制台输出到文本框控件"""
        cursor = self.textEdit.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.textEdit.setTextCursor(cursor)
        self.textEdit.ensureCursorVisible()

    def createrro(self):
        """人为制造一个错误,下面是一个不合规范的做法"""
        print(这是一个错误)

def redir_erro(mode, context, message):
    """【错误重定向】打印错误信息并且弹出警告窗口"""
    if mode == QtCore.QtInfoMsg:
        mode = 'INFO'
    elif mode == QtCore.QtWarningMsg:
        mode = 'WARNING'
    elif mode == QtCore.QtCriticalMsg:
        mode = 'CRITICAL'
    elif mode == QtCore.QtFatalMsg:
        mode = 'FATAL'
    else:
        mode = 'DEBUG'
    print('程序出错了')
    print(context)
    print('  %s: %s\n' % (mode, message))
    # errobox = QMessageBox.critical(None, 'Error', str(message))
    errobox = QtWidgets.QMessageBox()
    errobox.setWindowTitle('错误信息')
    errobox.setText(str(message))
    errobox.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)  # 设置文本可选中
    errobox.exec()




if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ui = Ui_Form()
    ui.show()

    QtCore.qInstallMessageHandler(redir_erro)  # 【错误重定向】

    print('这是一个输出重定向示例')

    sys.exit(app.exec_())

可以看到输出现在出现在了QTextEdit控件上,点击生成错误按钮后,弹出错误信息,而控制台是没有输出的。

下面来解释一下代码的含义。

class Stream(QObject):
    """【输出重定向】重定向控制台输出到文本框控件"""
    newText = pyqtSignal(str)
    # 任何定义了类似于文件write方法的对象可以指定给sys.stdout,所有的标准输出将发送到该方法对象上
    def write(self, text):
        self.newText.emit(str(text))
        QApplication.processEvents()
        # 【输出重定向】自定义输出流
        # sys.stdout = Stream(newText=self.onUpdateText)
        sys.stdout = Stream()
        sys.stdout.newText.connect(self.onUpdateText)

sys模块提供了python的标准输出流:sys.stdout,任何定义了类似于文件write方法的对象可以指定给sys.stdout,所有的标准输出将发送到该方法对象上,即OOP多态的概念。

QApplication.processEvents() 用于保证程序的流畅性和响应性。

Stream对象通过pyqtSignal方法将文本作为信号发送到主窗口中,连接到槽函数onUpdateText,这里也可以用一行代码完成,即 sys.stdout = Stream(newText=self.onUpdateText) ,因为默认情况下,QObjects可以接收到qproperties的初始值并连接qsignals。

接下来是输出错误信息的问题,这个更加麻烦,因为PyQt5一报错就会强制退出,所以这里不使用重定向sys.stderr的方法,而使用PyQt5提供的方法qInstallMessageHandler()

def redir_erro(mode, context, message):
    """【错误重定向】打印错误信息并且弹出警告窗口"""
    if mode == QtCore.QtInfoMsg:
        mode = 'INFO'
    elif mode == QtCore.QtWarningMsg:
        mode = 'WARNING'
    elif mode == QtCore.QtCriticalMsg:
        mode = 'CRITICAL'
    elif mode == QtCore.QtFatalMsg:
        mode = 'FATAL'
    else:
        mode = 'DEBUG'
    print('程序出错了')
    print(context)
    print('  %s: %s\n' % (mode, message))
    # errobox = QMessageBox.critical(None, 'Error', str(message))
    errobox = QtWidgets.QMessageBox()
    errobox.setWindowTitle('错误信息')
    errobox.setText(str(message))
    errobox.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)  # 设置文本可选中
    errobox.exec()
    QtCore.qInstallMessageHandler(redir_erro)  # 【错误重定向】

qInstallMessageHandler安装自定义的消息处理程序,返回指向上一个消息处理程序的指针,即回调函数。
消息处理程序是一个支持打印调试信息、警告、关键和致命错误信息的函数。利用这个可以把错误信息打印到QMessageBox中。

要注意的是QMessageBox关闭后,程序依然会强制退出。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值