实现一个多次pingIp功能,检验IP是否连接。使用QProcess::execute(QString)调用ping 命令时,发现ping窗口一直弹出闪烁,影响UI使用效果。调用代码为:
QString strIP = "127.0.0.1";
QString strInfo;
strInfo.sprintf("ping %s -n %d -i %d -w %d", strIP.toLocal8Bit().constData(), 2, 10, 200);
QProcess::execute(strInfo);
我们知道 QProcess::execute() 是同步启动新程序,启动程序时会阻塞当前进程,如果是UI线程就会卡住。但是为何会弹出ping窗口?通过QProcess::execute() 的源码我们发现:
int QProcess::execute(const QString &program)
{
QProcess process;
process.setReadChannelMode(ForwardedChannels);
process.start(program);
if(!process.waitForFinished(-1))
return -2;
return process.exitStatus() == QProcess::NormalExit? process.exitCode() : -1;
}
发现execute() 的PrcessChannelMode 写死为ForwardedChanels;
常量 | 值 | 描述 |
---|---|---|
QProcess::SeparateChannels | 0 | QProcess管理正在运行的进程的输出,将标准输出和标准错误数据保存在单独的内部缓冲区中。您可以通过调用setReadChannel()来选择QProcess的当前读取通道。这是QProcess的默认通道模式。 |
QProcess::MergedChannels | 1 | QProcess将正在运行的进程的输出合并到标准输出通道(stdout )中。标准错误通道(stderr )不会收到任何数据。正在运行的进程的标准输出和标准错误数据是交错的。 |
QProcess::ForwardedChannels | 2 | QProcess将正在运行的进程的输出转发到主进程。子进程写入其标准输出和标准错误的任何内容都将写入主进程的标准输出和标准错误。 |
QProcess::ForwardedErrorChannel | 4 | QProcess管理正在运行的进程的标准输出,但将其标准错误转发到主进程。这反映了命令行工具作为过滤器的典型用法,其中标准输出被重定向到另一个进程或文件,而标准错误被打印到控制台以用于诊断目的。(这个值是在Qt 5.2中引入的。) |
QProcess::ForwardedOutputChannel | 3 | ForwardedErrorChannel的补充。(这个值是在Qt 5.2中引入的。) |
通过表中描述,我们就发现原因了:QProcess::execute 将 pingIP的输出窗口转发到主进程了,所以一直有窗口闪烁。
这里我们设置 process.setReadChannelMode(ForwardedChannels); 通过重新封装一个新的execute() 函数,避免窗口闪烁问题。由于调用了 waitForFinished(-1) 函数,UI可能会卡顿,想避免UI卡顿就只能重新开个线程实现pingIp操作了。