将控制台打印的东西输出到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,发现错误内容被记录了进去,就说明该程序没有错误。
在这里插入图片描述

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

要将控制台内容显示到TextEdit上,首先需要获取控制台输出的内容。可以使用QProcess类来执行命令并获取其输出。 可以通过以下步骤实现: 1. 创建一个QProcess对象,用于执行命令并获取其输出。比如:QProcess *process = new QProcess(this)。 2. 使用QProcess的start()函数来启动需要执行的命令。例如,如果你想要执行一个名为command的命令,可以使用process->start("command")。 3. 连接QProcess的readyReadStandardOutput信号到一个槽函数。这个信号在命令执行完并有输出时被触发。在槽函数中可以获取输出内容,比如调用process->readAllStandardOutput()。 4. 将获取到的输出内容显示到TextEdit上。可以通过TextEdit的setText()函数来设置文本内容。例如,如果你有一个名为textEditTextEdit部件,可以使用textEdit->setText(output)将输出内容设置为textEdit的文本。 下面是一个简单的示例代码: ```cpp #include <QtWidgets> class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); textEdit = new QTextEdit(this); layout->addWidget(textEdit); setLayout(layout); // 创建QProcess对象 process = new QProcess(this); // 连接readyReadStandardOutput信号到槽函数 connect(process, &QProcess::readyReadStandardOutput, this, &Widget::readOutput); // 启动命令(示例:执行ls命令) process->start("ls"); } private slots: void readOutput() { // 获取输出内容 QByteArray output = process->readAllStandardOutput(); // 将内容显示到TextEdittextEdit->setPlainText(QString(output)); } private: QTextEdit *textEdit; QProcess *process; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); } #include "main.moc" ``` 以上是一个简单的示例代码,它执行了ls命令并将输出显示到了一个名为textEditTextEdit部件上。你可以根据实际情况修改和扩展这个代码来适应你的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值