Qt啟動子程序,子程序關閉時通知主程序,實現主程序對子程序的管理
自己開發了一個股票智慧分析軟體,功能很強大,需要的點選下面的連結獲取:
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();