背景:
windows,Qt5.12.7,py3.8.5
QProcess 运行python.exe 去执行一个py代码文件,代码文件内有print打印一些日志。
当py执行到打印到一些中文特殊符号时
会报错:'gbk' codec can't encode character '\u25aa' in position 49: illegal multibyte sequence
因为遍历文件夹时,有个文件的名称是:绿地▪安庆.docx。print的时候,直接抛异常。
原因:
这个点的编码超出了gbk。无论在哪加# -*- coding: utf-8 -*-,都没用,无法改变py内的print以gbk的编码输出。
可print(sys.stdout.encoding)查看py的标准输出编码确实是GBK,这是只读属性。
为了正常打印这个点,需要设置标准输出编码为utf-8。
注意到qt的QProcess:
QProcess 默认GBK,所以在获取标准输出时:
connect(m_process, SIGNAL(readyRead()), this, SLOT(onReadProcessData()));
connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadProcessData()));
connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(onReadProcessData()));
接收到标准输出后,需要将m_process->readAll()取得的字符串把GBK转为utf-8。
最终在这个地址找到:
https://www.cnblogs.com/vocus/p/11416022.html
原文里有一句: 在python2.x里面,可以通过设置环境变量PYTHONIOENCODING=ascii把sys.stdout.encoding改成ascii编码,但是在python3.x里面这种方法也行不通了
解决方案:
我这边是py3,环境变量PYTHONIOENCODING设置依旧有效
我的代码修改如下:
m_process = new QProcess(this);
//新增这三行
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("PYTHONIOENCODING", "utf-8");
m_process->setProcessEnvironment(env);
m_process->setReadChannelMode(QProcess::MergedChannels);
connect(m_process, SIGNAL(readyRead()), this, SLOT(onReadProcessData()));
connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadProcessData()));
connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(onReadProcessData()));
onReadProcessData里面获取m_process->readAll() 标准输出时,也不用转了,已经是utf-8了,也不会报错了。其实我有想过是qprocess的设置问题,只是不知道py编码的环境变量的名称是PYTHONIOENCODING,找了一天终于找到。