自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
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();