将控制台打印的东西输出到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.stdout
和sys.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
,发现错误内容被记录了进去,就说明该程序没有错误。
至于为啥那个界面不显示,暂且没找到原因。以上就大概完成这个功能。另外俩个坑很快就会填上.
本文来自博客园,作者:Bathwind_W,转载请注明原文链接:https://www.cnblogs.com/bathwind/p/18107952