进程的使用情况:

  • 运行的当前的应用中调用外部程序来实现功时调使用到进程。
  • 比如:在你的运行程序中,开启迅雷或开启其他程序
  • QProcess类用来 启动一个外部程序并与之通信

QProcess类

常用一些函数:

start()

开启进程,新进程中启动给定的程序,在参数中传递命令行参数

startDetached()

分离式,进程不会因为主程序的关闭而关闭

close()

关闭与进程的所有通信并终止它

kill()

终止当前进程,使其立即退出

terminate()

尝试终止进程

arguments()

返回上次启动进程时使用的命令行参数

atEnd()

如果进程未运行,并且没有更多数据可供读取返回true否则返回false

closeReadChannel()

关闭读取通道通道。调用此函数后,QProcess将不再接收通道上的数据。已收到的任何数据仍可供读取。

closeWriteChannel()

计划关闭 QProcess  的写入通道。将所有数据写入进程后,通道将关闭。调用此函数后,任何写入进程的尝试都将失败。

error()

返回上次发生的错误类型

execute()

阻塞

exitCode()

返回最后一个完成的进程的退出代码

exitStatus()

返回最后一个完成的进程的退出状态

open()

类似start(),但仅用于完全实现QIODevice定义的接口

processld()

返回正在运行的进程的本机进程标识符

program()

返回上次启动进程的程序

readAllStandardError()

无论当前读取通道如何,此函数都将进程标准错误中可用的所有数据作为 QByteArray 返回。

readAllStandardOutput()

无论当前读取通道如何,此函数都将进程标准输出中的所有可用数据作为 QByteArray 返回。

readChannel()

返回当前通道

readData()

读取数据

writeData()

写入数据

workingDirectory()

如果已为 QProcess 分配了一个工作目录,则此函数返回 QProcess 在程序启动之前将进入的工作目录。

state()

返回进程的当前状态

setWorkingDiaectory()

设置工作目录

setStandardOutPutProcess()

通过管道将此进程的标准输出流传送到目标进程的标准输入

setProgram()

设置启动进程时要使用的程序

setArguments()

设置在启动进程时要传递给被调用程序的参数

setInputChannelMode()

将 QProcess 标准输入通道的通道模式设置为指定的模式

setProcessChannelMode()

将 QProcess 标准输出和标准误差通道的通道模式设置为指定的模式

setProcessEnvironment()

设置 QProcess 将传递给子进程的环境

setProcessState()

指定状态

setReadChannel()

设置读取通道

setStandardErrorFile()

将进程的标准错误重定向到文件名。当重定向到位时,标准错误读取通道将关闭

setStandardInputFile()

将进程的标准输入重定向到文件名指示的文件

setStandardOutputFile()

将进程的标准输出重定向到文件名。当重定向到位时,标准输出读取通道将关闭

waitForBytesWrite(int)

阻塞,直到有数据写到进程

waitForFinished(int)

阻塞,直到进程完成并且发出 finish() 信号,或者直到毫秒后过去。

waitForReadyRead(int)

阻塞,直到当前通道上有可读的数据

waitForStarted(int)

阻塞,直到进程启动并发出 start() 信号,或者直到毫秒过去

信号:

errorHappen()

错误发生发出

done()

完成时发出

strated()

进程启动时发出

stateChanged()

状态发生变化时发出

QProcess 允许您将进程视为顺序 I/O 设备。您可以写入和读取进程,就像使用 QTcpSocket 访问网络连接一样。然后,您可以通过调用 write() 来写入进程的标准输入,并通过调用 read()、readLine() 和 getChar() 来读取标准输出。由于它继承了QIODevice,因此QProcess也可以用作QXmlReader的输入源,或者用于生成使用
QNextworkAccessManager上传的数据 

 启动一个程序的方式有两种:

  • strat()  主程序关闭, 进程也关闭
  • startDetached() 主程序关闭,进程不会关闭
QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)

//第一个参数为:需要打开的程序
//第二个参数为:传递的命令行参数,程序会执行该命令
//第三个参数为:打开模式,一般使用默认值

//第一种创建的格式:
QString program="路径"
QStringList arguments;
arguments<<"命令"<<...(可以有多个);
process->start(program,arguments);//启动
//第二种创建的格式:

QString program="路径"
QStringList arguments;
arguments<<"命令"<<...(可以有多个);
process->setProgram(program);//设置程序
process->setArguments(arguments);
process->start();//启动

启动一个系统进程:

在头文件中添加:

QProcess *p;//进程对象

在构造函数中添加:

p=new QProcess(this);
    p->start("notepad.exe");//开启进程

notepad.exe 为记事本,因为该程序的具体目录添加到系统PATH,所以不用具体给出

 运行结果:

qt 进程 create process qt打开进程_Qt

启动非系统程序:

获取桌面软件路径的方法:

1.右键点击该软件,点击属性

qt 进程 create process qt打开进程_qt_02

2.复制该目标里面的路径即可

qt 进程 create process qt打开进程_List_03

使用时把 \ 改为\\ 或 /(这是路径访问的规则)
 原路径: D:\迅雷下载\Thunder\Program\ThunderStart.exe
修改后的路径 :D:\\迅雷下载\\Thunder\\Program\\ThunderStart.exe
                          或D:/迅雷下载/Thunder/Program/ThunderStart.exe 
 非系统程序路径的规则
• 路径内有空格,不能直接启动(启动不了)
• 有空格的话可以使用带参模式才可以启动
带参模式的格式:process->start("路径",QStringList("路径"))

1.路径带空格启动不了 

//使用带空格的路径不会启动
p->start("C:/Program Files (x86)/QQ/Bin/QQScLauncher.exe");//启动不了QQ

2. 不带空格的路径可以直接启动

//不带空格的可以启动
p->start("D:/迅雷下载/Thunder/Program/ThunderStart.exe");//启动迅雷

qt 进程 create process qt打开进程_qt_04

3.带空格的路劲可以使用带参模式启动 

p->start("C:/Program Files (x86)/QQ/Bin/QQScLauncher.exe"
             ,QStringList("C:/Program Files (x86)/QQ/Bin/QQScLauncher.exe"));//启动QQ

qt 进程 create process qt打开进程_数据_05

  使用参数来执行命令:

//使用Qt Creator 打开一个项目
    QStringList list;
    list<<"D:/Qt_Android_work/UDP_Socket/UDP_Socket.pro";//存放项目路径
    //打开Qt Creator 打开 UDP_Socket项目
    p->start("D:/QT/Tools/QtCreator/bin/qtcreator.exe",list);

运行结果:

qt 进程 create process qt打开进程_Qt_06

使用信号可以获取一些信息:

创建一个新项目:

头文件中添加:

QProcess *process;

ui界面中添加两个QPushButton (打开进程),转到槽选择clicked()信号       

qt 进程 create process qt打开进程_Qt_07

 .cpp的全部内容:

#include "process.h"
#include "ui_process.h"
#include<QProcess>
#include<QDebug>
#include<QMessageBox>
process::process(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::process)
{
    ui->setupUi(this);

    p=new QProcess(this);
    connect(p,&QProcess::started,[=]()//启动完成
    {
        qDebug()<<"进程已启动";
    });
    connect(p,&QProcess::stateChanged,[=]()//进程状态改变
    {
        if(p->state()==QProcess::Running)
        {
            qDebug()<<"正在运行";
        }
        else if(p->state()==QProcess::NotRunning)
        {
            qDebug()<<"不在运行";
        }
        else
        {
            qDebug()<<"正在启动";
        }
    });
    connect(p,&QProcess::errorOccurred,[=]()
    {
        qDebug()<<p->errorString();//输出错误信息
    });
}

process::~process()
{
    delete ui;
}

void process::on_pushButton_clicked()//开起进程
{
    p->start("C:\\Program Files (x86)\\QQ\\Bin\\QQScLauncher.exe",
             QStringList("C:\\Program Files (x86)\\QQ\\Bin\\QQScLauncher.exe"));//开启QQ登录程序
}

 同步进程接口:

QProcess 提供了一组函数,允许在没有事件循环的情况下使用它,方法是挂起调用线程直到发出某些信号

  • waitForStarted()直到进程启动
  • waitForReadyRead() 直到新数据可用于当前读取通道上的读取
  • waitForBytesWrite() 直到一个数据有效负载被写入进程
  • waitForDone()直到进程完成

官方案例:

 下面的示例运行以压缩字符串“Qt rocks!”,而不使用事件循环:gzip

QProcess gzip;
    gzip.start("gzip", QStringList() << "-c");
    if (!gzip.waitForStarted())
        return false;

    gzip.write("Qt rocks!");
    gzip.closeWriteChannel();

    if (!gzip.waitForFinished())
        return false;

    QByteArray result = gzip.readAll();

参考文档:

Q课程|类Qt核心 5.15.12