自己開發了一個股票智能分析軟件,功能很強大,需要的點擊下面的鏈接獲取:
https://www.cnblogs.com/bclshuai/p/11380657.html
1.需求描述
Qt主進程啟動之后,在啟動一個程序的四個子進程,子進程關閉時,會通過狀態改變信號,通知主進程的槽函數,實現刪除子進程的管理QProcess* 變量;
2.Qt進程QProcess介紹
2.1進程啟動方式
有兩種啟動方式,start是父子進程關聯啟動子進程。startDetached則是以分離的方式啟動進程。
void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
void start(const QString &command, OpenMode mode = ReadWrite);
void start(OpenMode mode = ReadWrite);
static bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory
static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads
static bool startDetached(const QString &command);
3.實現步驟
(1)創建QMap保存進程的QProcess* 變量;
QMap<int,QProcess*> m_processMap;
(2)主進程中獲取子進程路徑,通過for循環啟動四個子進程,並傳入命令行參數,同時將for循環的ii值作為map的key值,用於標記是哪個進程。綁定stateChanged信號槽,之前打算用finish信號,但是finish信號有個重載函數,所以使用connect連接時,&QProcess::finished,無法判斷是哪個函數,所以不行。如果用SIGNAL(finish(int exitCode)),又無法用SLOT去定義lamlar表達式。為了實現i序號作為進程的標識id,進程狀態改變時,觸發信號,可以定位到是哪個進程結束了,直接在map中刪除該進程變量。就可以了方便實現主進程和子進程之間的管理
void finished(int exitCode); // ### Qt 6: merge the two signals with a default value
void finished(int exitCode, QProcess::ExitStatus exitStatus)
QString strProcessPath = QDir::currentPath() + "/AlgAnalyizeTool/AlgAnalyizeTool.exe";//AlgAnalyizeTool.exe if (!QFile(strProcessPath).exists()) { QMessageBox::information(NULL, "提示", "分析進程不存在", QMessageBox::Yes, QMessageBox::Yes); return; } for (int i = 0; i < 4; i++) { QJsonObject jsonMain; QJsonObject serverConf; QJsonObject videoAnalyizeConf; videoAnalyizeConf.insert("cpuCores", 4); videoAnalyizeConf.insert("gpuNo", i); videoAnalyizeConf.insert("threadCount", 4); serverConf.insert("ip", "10.25.106.103"); serverConf.insert("port", 8011); serverConf.insert("sessionId", QString::number(i)); jsonMain.insert("serverConf", serverConf); jsonMain.insert("videoAnalyizeConf", videoAnalyizeConf); QJsonDocument root_Doc; root_Doc.setObject(jsonMain); QByteArray root_str = root_Doc.toJson(QJsonDocument::Compact); //緊湊格式 // QByteArray root_str = root_Doc.toJson(QJsonDocument::Indented); //標准JSON格式 QString strJson(root_str); QString strJson((root_str.toBase64())); QStringList Qstringlist; Qstringlist << strJson; QProcess* process=new QProcess(this); connect(process,&QProcess::stateChanged, this, [=](QProcess::ProcessState state) { if (state== QProcess::ProcessState::NotRunning) { QMap<int, QProcess*>::iterator it = m_processMap.find(i); if (it != m_processMap.end()) { delete it.value(); m_processMap.erase(it); } } }); LOG_TRACE("start begin! "); process->start(strProcessPath, Qstringlist); m_processMap[i] = process; LOG_TRACE("start end! "); }
4.注意事項
4.1.主進程退出前先關閉子進程並釋放資源
以start方式啟動的子進程,需要在主進程關閉的析構函數中關閉主進程,並且刪除new出的進程指針變量;才可以正常退出。否則,資源管理器中會保留主進程和子進程。導致程序無法覆蓋或編譯生成報錯。
QMap<int, QProcess*>::iterator it = m_processMap.begin(); for (;it!=m_processMap.end();it++) { it.value()->terminate(); delete it.value(); } m_processMap.clear();
