我們常常想通過某一個類,來啟動一個外部進程
本文將講解如何通過QProcess來進行啟動外部進程
一:了解QProcess
QProcess是Qt框架提供的一個類,用于在應用程序中執行外部進程。它提供了一系列函數來啟動、控制和與外部進程進行交互
1.啟動進程的方式:
(1.1)分離式:外部程序啟動程序后,主程序退出時,被調用的進程繼續執行,不退出
[static] bool QProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)
(1.2)一體式:當主程序退出時,被主程序調用起來的進程也退出
start還有其他的重載的函數,下面是其中一個
void QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)
2:常用的阻塞函數
// 主進程阻塞,直到外部程序啟動完畢,
waitForStarted()// 主進程阻塞,直到外部程序執行完畢
waitForFinished()
3:被調用進程接受數據
4:主進程接受被調用進程的數據
(4.1)使用QFile輸出內容被 主進程捕獲
QFile file;
file.open(1, QFile::WriteOnly);
file.write("finished");
file.close();
(4.2)使用輸出流 被 主進程捕獲
cout << "it's message" << endl;
5:常用的信號
//啟動完畢
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 依然可以接受
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 可以接受參數
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完成(關閉軟件)
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完成(關閉軟件)
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使用 四