QT 关于QProcess的一些总结

QProcess 常被用来启动外部程序,并且可以与之进行通讯。本文总结了开发过程中,QProcess的常用操作,部分内容借鉴网上。

QProcess启动外部程序,并获取其输出信息

首先新建一个外部程序(QtConsole.exe),供QProcess调起使用,其代码如下:

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

	std::cout << "------QtConsole's output------std::cout" << std::endl;
	QStringList arguments = QCoreApplication::arguments();
	for (auto v : arguments)
	{
		std::cout << "arguments=" << v.toStdString().c_str() << std::endl;
	}
	std::cout << "------QtConsole's output------QDebug" << std::endl;
	for (auto v : arguments)
	{
		qDebug() << "arguments=" << v;
	}

	//return a.exec();
	//system("pause");
	return 0;
}

使用execute或start启动外部程序,被调用函数的标准输入/输出/出错,都已被重定向到QProcess创建的相应的管道中。

  • execute 启动外部程序
    execute()是阻塞的,execute()=start()+waitforFinished()
  • start 启动外部程序
    start()是非阻塞的,调起的QtConsole.exe不会显示界面(只会存在于任务管理器的进程列表中)
    需要等到QtConsole.exe的进程结束,QProcess的readAll才能读取到QtConsole.exe中std::cout输出的内容
#include 
#include 
#include 
#include 
#include 


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

	QProcess* process = new QProcess;
	QObject::connect(process, &QProcess::started, [=]()
		{
			qDebug() << "QProcess::started";
		});
	QObject::connect(process, &QProcess::readyRead, [=]()
		{
			qDebug() << "readyRead-readAll:";
			qDebug() << QString::fromLocal8Bit(process->readAll());
			qDebug() << "readyRead-readAllStandardOutput:";
			qDebug() << QString::fromLocal8Bit(process->readAllStandardOutput());
		});
	QObject::connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus)
		{
			//QProcess::ExitStatus(QProcess::NormalExit/CrashExit)
			qDebug() << "exitCode=" << exitCode << ", exitStatus=" << exitStatus;
			
			if (exitStatus == QProcess::NormalExit)
			{
				qDebug() << "finished-readAll:";
				qDebug() << QString::fromLocal8Bit(process->readAll());
				qDebug() << "finished-readAllStandardOutput:";
				qDebug() << QString::fromLocal8Bit(process->readAllStandardOutput());
			}
			else if (exitStatus == QProcess::CrashExit)
			{
				qDebug() << "QProcess::CrashExit";
			}
			else
			{
				qDebug() << "QProcess::???";
			}
		});	
	QObject::connect(process, &QProcess::stateChanged, [=](QProcess::ProcessState processState)
		{
			//QProcess::ProcessState(QProcess::NotRunning/Starting/Running)
			//QProcess::ProcessState processState = process->state();
			qDebug() << "ProcessState=" << processState;
		});
	QObject::connect(process, &QProcess::errorOccurred, [=](QProcess::ProcessError processError)
		{
			//QProcess::ProcessError(FailedToStart/Crashed/Timedout/ReadError/WriteError/UnknownError)
			qDebug() << "QProcess::ProcessError=" << processError;
		});

	//启动外部程序(QtConsole.exe)
	QString program = "QtConsole.exe";
	QStringList startArgs;
	startArgs << "gameName=Test" << "maxPlayer=3" << "minPlayer=1";

	/*
	* execute()是阻塞的,execute()=start()+waitforFinished()
	* QtConsole.exe的输出(包括qDebug的输出)会显示在本进程的窗口显示
	*/
	process->execute(program, startArgs);

	/*
	* start()是非阻塞的,调起的QtConsole.exe不会显示界面(只会存在于任务管理器的进程列表中)
	* 需要等到QtConsole.exe的进程结束, QProcess的readAll才能读取到QtConsole.exe中std::cout输出的内容
	*/
	//process->start(program, startArgs);
	//process->waitForFinished();
	
	system("pause");
	return 0;
}

上述代码(process->execute(program, startArgs);)运行结果:
QT 关于QProcess的一些总结_第1张图片
上述代码(process->start(program, startArgs); process->waitForFinished();)运行结果:
QT 关于QProcess的一些总结_第2张图片

  • startDetached 启动外部程序
    • <1>
      QString cmdstr = "cmd.exe /c QtConsole.exe --path ./editor --game \"a b c\" --lang zh";
      QProcess::startDetached(cmdstr);
      
    • <2>
      qint64 pid = 0;
      QStringList param;
      param << "--path";
      param << "./editor";
      param << "--game";
      param << "\"a b c\"";
      param << "--lang";
      param << "--zh";
      QProcess::startDetached("QtConsole.exe", param, "", &pid);
      

根据进程名字杀掉进程

QProcess p;
QString cmd = "taskkill /im QtConsole.exe /f";
p.execute(cmd);
//p.start(cmd);
//p.waitForFinished();
p.close();

根据进程ID杀掉进程

QString strCommand = QString("taskkill /pid %1 /f").arg(pid);
		//<1>
		int code = system(strCommand.toStdString().c_str());
		qDebug() << "code=" << code;

		//<2>
		process->start(strCommand);

		//<3>
		code = process->execute(strCommand);
		qDebug() << "code=" << code;//0

start 与 startDetached 的区别

start是一体式的:外部程序启动后,将随主程序的退出而退出;
startDetached是分离式的:外部程序启动后,不会随主程序的退出而退出。
重要区别:如果是start则回调都可以正常接收到信息;如果是startDetached则回调无法正常接收到信息。

你可能感兴趣的:(#,Qt,进阶篇,QProcess,start,execute,startDetached,waitForFinished)