将控制台打印的东西输出到textedit控件上

因为大创要做一个人脸测温的项目部署到树莓派上,所以界面是必须的,pyqt5比较幸运的之前我也接触过,由于需要将控制台输出的结果转移到界面上便于调试和观察,实现的具体效果为:
在这里插入图片描述

实现的具体效果大概就是这个样子,实际在程序里面写的时候还是用printf()语句去打印,只不过相当于把printf打印的地方换了一个地方输出。
程序里面涉及到了sys模块,sys这个模块是python中一个很重要的模块。下面是sys比较常用的函数列表

sys.argv: 实现从程序外部向程序传递参数。
sys.exit([arg]): 程序中间的退出,arg=0为正常退出。
sys.getdefaultencoding(): 获取系统当前编码,一般默认为ascii。
sys.setdefaultencoding(): 设置系统默认编码,执行dir(sys)时不会看到这个方法,在解释器中执行不通过,可以先执行reload(sys),在执行 setdefaultencoding('utf8'),此时将系统默认编码设置为utf8。(见设置系统默认编码 )
sys.getfilesystemencoding(): 获取文件系统使用编码方式,Windows下返回'mbcs',mac下返回'utf-8'.
sys.path: 获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。
sys.platform: 获取当前系统平台。
sys.stdin,sys.stdout,sys.stderr: stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们

思路的话参考的网上其他大佬的程序,具体思路是首先定义一个类:
程序具体为:

# 重定向信号
class EmittingStr(QtCore.QObject):
        textWritten = QtCore.pyqtSignal(str)  # 定义一个发送str的信号
        def write(self, text):
            self.textWritten.emit(str(text))
            loop = QEventLoop()
            QTimer.singleShot(1000, loop.quit)
            loop.exec_()

QtCore.pyqtSignal的作用是创建一个发送str的信号,之后就对这个创建的信号进行操作,这部分又涉及到了Pyqt5中的信号与槽的机制的知识,莫名觉得又挖了一个坑进去。
下面是信号与槽机制的解释:
在这里插入图片描述
当事件或者状态发生改变时,就会发出信号,同时的话,信号也会触发所有与这个事件(信号)相关的函数(槽),信号与槽的话可以多对多的关系,一个信号可以连接多个槽,一个槽也可以监听多个信号。

由于Pyqt的内置信号是自动定义的。使用QtCore.pyqtSignal()函数可以为Qobject创建一个信号,使用这个函数可以自定义信号的属性,使用这个函数创建信号时候,信号可以传递多个参数,并指定信号传递参数的类型,参数类型必须是标准的Python数据类型(字符串,日期,布尔类型,数字,列表,元组和字典)。信号与槽的运用我打算单独再写出一篇。又挖了一个大坑,啊哈哈哈哈,o( ̄︶ ̄)o。

程序下面一句自定义了一个write函数,第一句emit函数的作用就是可以发射一个信号,这个步骤也是信号与槽的必须的一个步骤。

QEventLoop这个函数的作用就是创建一个局部的循环。

  • 创建事件循环

  • 启动定时器,让其100ms后触发事件循环的quit()槽

  • 启动事件循环

2:写一个关于操控textedit控件的函数:

   def outputWritten(self, text):
        # self.textEdit.clear()
        cursor = self.textEdit.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.textEdit.setTextCursor(cursor)
        self.textEdit.ensureCursorVisible()

这一段程序主要是对texteidt这个控件进行文本操作。这里涉及到了光标操作(我自己给自己又挖了一个坑,一会这篇写完专门写一篇来介绍这个光标位置的使用,这一段程序可以理解为对文本的操作。

3:最后在你的类里面添加这俩句程序即可:

        sys.stdout = EmittingStr(textWritten=self.outputWritten)
        sys.stderr = EmittingStr(textWritten=self.outputWritten)

sys.stdoutsys.stderr这俩个就要划重点了。

sys.stdout 与 print的作用基本类似,可以看作print就是sys.stdout的进一步封装,们在 Python 中打印对象调用 print obj 时候,事实上是调用了 sys.stdout.write(obj+'\n'),print 将你需要的内容打印到了控制台,然后追加了一个换行符
print 会调用 sys.stdout 的 write 方法以下两行在事实上等价:

sys.stdout.write('hello'+'\n') 
print 'hello'

咱们的目的是把控制台信息重定向到Textedit上,下面有一个网上的例子很好理解,就是把控制台的信息同时定向到文件和控制台输出。

具体代码:

f_handler=open('out.log', 'w') 
sys.stdout=f_handler 
print("Hello World")

这个就是把控制台输出的信息存储到文件当中,也就是out.log这个文件中。看完这个例子是不是有了想法,咱们把是不是只要把控制Textedit的赋值给sys.stdout,这样不就可以了。

是不是非常的amazing!!!。sys.stderr这个东东我百度说的是用sys.stderr 目的就是返回错误信息,但是我在界面里面的程序尝试写了一个1%0的bug,发现Textedit里面并没有显示相应的错误。莫非pyqt5界面和这个有冲突。

抱着试一试的态度,我单独写了一个程序实验,发现单独用是好使的:

f_handler=open('out.log', 'w')
sys.stderr=f_handler
a = 1%0
print(a)

这很明显有错误,对吧。然后我打开生成的out.log,发现错误内容被记录了进去,就说明该程序没有错误。
在这里插入图片描述

至于为啥那个界面不显示,暂且没找到原因。以上就大概完成这个功能。另外俩个坑很快就会填上.

  • 1
    点赞
  • 0
    评论
  • 8
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值