跳转至

Qt5与Qt6中QProcess::start()执行的差异

在Qt 5和Qt 6中执行QProcess::start()效果的不同,在Qt 5上默认会调用一个过时的函数,Qt 6将这个过时的函数删除了,在Qt 5的一个同名不同参数的函数的第二个参数添加了默认参数,会调用它。就导致执行的不同。 如果想要执行带参数的命令,需要将参数变成QStringList输入,在Qt5和Qt6中都能正确执行。

1. 缘起

例如,在Windows上,我想获取CPU的序列号,查询到可以使用wmic cpu get processorid 命令,在powershell中执行如下:

PS C:\Users\china-newer> wmic cpu get processorid
ProcessorId
BFEBFBF*******EA
在我的程序中,正好需要获取这些硬件的序号,计划使用Qt进行获取。

2. 发现

在网上检索到,可以使用类似于如下的命令获取结果:

QProcess p;
p.start("wmic wmic cpu get processorid");
p.waitForFinished();
qDebug() << p.readAllStandardOutput();

3. 试错

我在代码中进行测试,输出的结果为空字符串。
使用的尝试失败。

4. 缘由

首先,在网上好多的人的博客中都有这样的,说明这段代码在某种程度上应该是能够执行的。

我现在使用的Qt环境是Qt6,并且在那些Blog下面没有看到提出不能执行的评论,所以我在想,是否是因为Qt6刚开始使用的时间短,没有人发现呢?
于是,我尝试下Qt5(Qt 5.15.2)执行上面的代码,发现可以执行,输出如下的结果:

"ProcessorId       \r\r\nBFEBFBF*******EA  \r\r\n\r\r\n"
在执行的时候,在代码上面可以看到如下的提示:

看来,这就是原因,这个函数在Qt 5中已经被标记为过时了,在Qt6里面的时候应该是不再使用了。

4.1 Qt 5 API

查看Qt 5的帮组文档,描述如下:

void QProcess::start(const QString &command, QIODevice::OpenMode mode = ReadWrite) This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.

可以看到其含义是此函数过时,不建议使用。
同样能够查到如下的函数声明:

void QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)

4.2 Qt 6 API

在Qt 6中,实际调用的函数如下:

void QProcess::start(const QString &program, const QStringList &arguments = {}, QIODeviceBase::OpenMode mode = ReadWrite)

4.3 Qt 5和Qt 6中调用的差异

查看相关的Qt 5文档,发现这个函数(Qt 6中调用的函数)在Qt 5中已经存在,只是Qt 6使用了默认参数。
在Qt 5和Qt 6看是相同的方法,实际上调用了不同的函数。

5. 斧正

根据Qt 6相关的API,需要将参数变成一个QStringList,那么执行如下代码进行测试:

执行的测试

QProcess p;
QStringList sl; 
sl << "CPU" <<  "get" << "processorid";
p.start("wmic",sl);
p.waitForFinished();
qDebug() << p.readAllStandardOutput();
发现输入了与Qt 5中执行相同的结果。