QT笔记——QProcess学习

我们常常想通过某一个类,来启动一个外部进程

本文将讲解如何通过QProcess来进行启动外部进程

一:了解QProcess

QProcess是Qt框架提供的一个类,用于在应用程序中执行外部进程。它提供了一系列函数来启动、控制和与外部进程进行交互

1.启动进程的方式:

(1.1)分离式:外部程序启动程序后,主程序退出时,被调用的进程继续执行,不退出

cpp 复制代码
[static] bool QProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)

(1.2)一体式:当主程序退出时,被主程序调用起来的进程也退出

start还有其他的重载的函数,下面是其中一个

cpp 复制代码
void QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)

2:常用的阻塞函数

cpp 复制代码
// 主进程阻塞,直到外部程序启动完毕,
waitForStarted()
 
// 主进程阻塞,直到外部程序执行完毕
waitForFinished() 

3:被调用进程接受数据

cpp 复制代码
QStringList list = QCoreApplication::arguments();
//为什么试3个呢,我明明参数是传的两个  因为第一个参数是我们传的exe启动 全路径 C:\Users\admin\Desktop\a.exe
if (list.size() == 3)
{
	QString exeFileName= list.at(0);
	QString oneStr = list.at(1);
	QString twoStr= list.at(2);
}

4:主进程接受被调用进程的数据

(4.1)使用QFile输出内容被 主进程捕获

cpp 复制代码
QFile file;
file.open(1, QFile::WriteOnly);
file.write("finished");
file.close();

(4.2)使用输出流 被 主进程捕获

cpp 复制代码
 cout << "it's message" << endl;

5:常用的信号

cpp 复制代码
//启动完毕
connect(process, &QProcess::started, this, [=]()
{
			
});

//捕获到消息时
connect(process, &QProcess::readyReadStandardOutput, this, [=]()
{

});

//完成
connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int exitCode, QProcess::ExitStatus exitStatus)
{

});

//状态改变
connect(process, &QProcess::stateChanged, this, [=](QProcess::ProcessState state)
{
	
});

二:使用QPrecess

1:startDetached 启动进程

1:使用了startDetached来启动进程,信号都是无效的,接受不到任何消息

2:当主进程关闭时,被调用的QTcpClientTest.exe 是不会退出的

3:主进程发送的参数,被调用的QTcpClientTest.exe 依然可以接受

cpp 复制代码
void QTcpSeverTest::on_btn1_clicked()
{
	QProcess* process = new QProcess(this);
	QString str = QApplication::applicationDirPath() + "/QTcpClientTest.exe";

	QStringList list;
	list.append("123");
	list.append("456");

	//分离式 启动外部进程
	process->startDetached(str, list);
	
	//无效
	connect(process, &QProcess::started, this, [=]()
		{
			qDebug() << "started";
		});

	//无效
	connect(process, &QProcess::readyReadStandardOutput, this, [=]()
		{
			QString qstr(process->readAllStandardOutput());
			qDebug() << "startDetached:" << qstr;
		});

	connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int exitCode, QProcess::ExitStatus exitStatus)
		{
			QString result = process->readAll();
			qDebug() << "result:" << result;
		});

	//无效
	connect(process, &QProcess::stateChanged, this, [=](QProcess::ProcessState state)
		{
			qDebug() << "show state:";
			switch (state)
			{
			case QProcess::NotRunning:
				qDebug() << "Not Running";
				break;
			case QProcess::Starting:
				qDebug() << "Starting";
				break;
			case QProcess::Running:
				qDebug() << "Running";
				break;
			default:
				qDebug() << "otherState";
				break;
			}

		});

}

2:start启动进程

1:使用了startDetached来启动进程,信号都是可以接受的

2:当主进程关闭时,被调用的QTcpClientTest.exe 是随着主进程一起退出

3:主进程发送的参数,被调用的QTcpClientTest.exe 可以接受参数

cpp 复制代码
	QProcess* process = new QProcess(this);
	QString str = QApplication::applicationDirPath() + "/QTcpClientTest.exe";

	QStringList list;
	list.append("bbbbb");
	list.append("aaaaa");

	//启动完毕
	connect(process, &QProcess::started, this, [=]()
	{
			qDebug() << "started:" ;
	});

	//捕获到消息时
	connect(process, &QProcess::readyReadStandardOutput, this, [=]()
	{
			QString qstr(process->readAllStandardOutput());
			qDebug() << "readyReadStandardOutput:" << qstr;
	});

	//完成
	connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int exitCode, QProcess::ExitStatus exitStatus)
	{
			if (exitStatus == QProcess::NormalExit) {
				qDebug() << "Process finished with exit code:" << exitCode;
			}
			else {
				qDebug() << "Process crashed!";
			}
	});

	//状态改变
	connect(process, &QProcess::stateChanged, this, [=](QProcess::ProcessState state)
	{
			qDebug() << "show state:";
			switch (state)
			{
			case QProcess::NotRunning:
				qDebug() << "Not Running";
				break;
			case QProcess::Starting:
				qDebug() << "Starting";
				break;
			case QProcess::Running:
				qDebug() << "Running";
				break;
			default:
				qDebug() << "otherState";
				break;
			}

	});

	//一体式  启动外部进程
	process->start(str, list);

3:execute()启动进程

1:使用了execute来启动进程,信号是无效的

2:主进程一直处于阻塞状态,等待被调用的QTcpClientTest.exe完成(关闭软件)

cpp 复制代码
	QProcess* process = new QProcess(this);
	QString str = QApplication::applicationDirPath() + "/QTcpClientTest.exe";

	QStringList list;
	list.append("bbbbb");
	list.append("aaaaa");

	//无效
	connect(process, &QProcess::started, this, [=]()
		{
			qDebug() << "started:";
		});

	//无效
	connect(process, &QProcess::readyReadStandardOutput, this, [=]()
		{
			QString qstr(process->readAllStandardOutput());
			qDebug() << "readyReadStandardOutput:" << qstr;
		});

	//无效
	connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [=](int exitCode, QProcess::ExitStatus exitStatus)
		{
			QString result = process->readAll();
			qDebug() << "result:" << result;
		});

	//无效
	connect(process, &QProcess::stateChanged, this, [=](QProcess::ProcessState state)
		{
			qDebug() << "show state:";
			switch (state)
			{
			case QProcess::NotRunning:
				qDebug() << "Not Running";
				break;
			case QProcess::Starting:
				qDebug() << "Starting";
				break;
			case QProcess::Running:
				qDebug() << "Running";
				break;
			default:
				qDebug() << "otherState";
				break;
			}

		});

	//如果进程 QTcpClientTest 不关闭 或者完成 , 则此进程一直卡住
	int exitCode = QProcess::execute(str, list);
	if (exitCode != 0) {
		qDebug() << "外部程序执行失败";
	}

	//接受进程捕获到输出的消息
	QByteArray output = process->readAllStandardOutput();
	QString msg = QString::fromLocal8Bit(output);
	qDebug() << msg;

打印的信息为:QIODevice::read (QProcess): device not open,说明execute没有打开设备,接受不到消息

4:start() + waitForFinished()启动进程

1:使用了execute来启动进程,信号是无效的

2:主进程一直处于阻塞状态,等待被调用的QTcpClientTest.exe完成(关闭软件)

cpp 复制代码
	QProcess* process = new QProcess(this);
	QString str = QApplication::applicationDirPath() + "/QTcpClientTest.exe";

	QStringList list;
	list.append("bbbbb");
	list.append("aaaaa");

	//启动进程
    process->start(str,list);

    // 等待进程完成
    process->waitForFinished();

	//接受进程捕获到输出的消息
    QByteArray output = process->readAllStandardOutput();
    QString msg = QString::fromLocal8Bit(output);
    qDebug() << msg;

完整代码:
QProcess完整学习代码

参考博客:
QProcess使用 一
QProcess使用 二
QProcess使用 三
QProcess使用 四
QProcess使用 五

相关推荐
躺着听Jay20 分钟前
Oracle-相关笔记
数据库·笔记·oracle
田梓燊24 分钟前
数学复习笔记 19
笔记·线性代数·机器学习
前端小崔42 分钟前
从零开始学习three.js(18):一文详解three.js中的着色器Shader
前端·javascript·学习·3d·webgl·数据可视化·着色器
春蕾夏荷_7282977251 小时前
Qt 强大的窗口停靠浮动
qt·停靠·dock
逼子格1 小时前
硬件工程师笔记——二极管Multisim电路仿真实验汇总
笔记·嵌入式硬件·硬件工程师·multisim·硬件工程师学习·电子器件·电路图
龙湾开发2 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(二)法线贴图
c++·笔记·学习·图形渲染·贴图
新手村领路人2 小时前
qt5.14.2 opencv调用摄像头显示在label
qt·opencv·命令模式
liang_20262 小时前
【HT周赛】T3.二维平面 题解(分块:矩形chkmax,求矩形和)
数据结构·笔记·学习·算法·平面·总结
虾球xz2 小时前
游戏引擎学习第290天:完成分离渲染
c++·人工智能·学习·游戏引擎
虾球xz2 小时前
游戏引擎学习第285天:“Traversables 的事务性占用”
c++·学习·游戏引擎