自己開發了一個股票智慧分析軟體,功能很強大,需要的點選下面的連結獲取:
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();