自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

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 = ; i < ; i++)
{
QJsonObject jsonMain;
QJsonObject serverConf;
QJsonObject videoAnalyizeConf;
videoAnalyizeConf.insert("cpuCores", );
videoAnalyizeConf.insert("gpuNo", i);
videoAnalyizeConf.insert("threadCount", );
serverConf.insert("ip", "10.25.106.103");
serverConf.insert("port", );
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();

QString strProcessPath = QDir::currentPath() + "/AlgAnalyizeTool/AlgAnalyizeTool.exe";//AlgAnalyizeTool.exeif (!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! ");}

Qt启动子进程,子进程关闭时通知主进程,实现主进程对子进程的管理的更多相关文章

  1. 程序启动读取和关闭时保存应用程序设置(QSettings)

    保存应用程序设置(QSettings)1. QSettings 类 QSettings 提供保存应用程序当前设置的接口,可以方便地保存程序的状态,例如窗口大小和位置,选项的选中状态等等.在 Windo ...

  2. 运用pool进程池启动大量子进程

    # Pool进程池类 from multiprocessing import Pool import os import time import random def run(index): prin ...

  3. qt 单文档程序关闭时在delete ui处出现segmentation fault

    做了个显示图片的单文档程序. qt 单文档程序关闭时在delete ui处出现segmentation fault. 调试发现调用两次mainwindow析构函数. http://blog.csdn. ...

  4. Qt窗体关闭时,如何自动销毁窗体类对象

    Qt窗体关闭时,如何自动销毁窗体类对象     要对你的窗口设置WA_DeleteOnClose属性,默认的情况下关闭窗口仅仅意味着隐藏它 ImgWindow1->setAttribute(Qt ...

  5. 线程_使用multiprocessing启动一个子进程及创建Process 的子类

    from multiprocessing import Process import os # 子进程执行的函数 def run_proc(name): print("子进程运行中,名称:% ...

  6. qt 启动参数 -qws

    运行嵌入式程序 在嵌入式QT版本中,程序需要服务器或自己作为服务器程序. 服务器程序构造的方法是构造一个QApplication::GuiServe类型的QApplication对象.或者使用-qws ...

  7. Oracle数据库体系结构、启动过程、关闭过程

    一.Oracle数据库体系结构体系结构由下面组件组成:1.Oracle服务器(Server):由数据库实例和数据库文件组成,另外在用户建立与服务器的连接时启动服务器进程并分配PGA(程序全局区) (1 ...

  8. C# 程序异常关闭时的捕获

    本文主要以一个简单的小例子,描述C# Winform程序异常关闭时,如何进行捕获,并记录日志. 概述 有时在界面的事件中,明明有try... catch 进行捕获异常,但是还是会有异常关闭的情况,所以 ...

  9. pyqt pyside 设置窗口关闭时删除自身

    pyqt pyside 设置窗口关闭时删除自身 self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

随机推荐

  1. [草稿] Linux 各种 打包 / 解包 命令

    https://www.cnblogs.com/yeungchie/ 有不少错误 .tar格式 解包: tar -xvf FileName.tar 打包: tar -cvf FileName.tar ...

  2. ElasticSearch 基础入门 and 操作索引 and 操作文档

    基本概念 索引: 类似于MySQL的表.索引的结构为全文搜索作准备,不存储原始的数据. 索引可以做分布式.每一个索引有一个或者多个分片 shard.每一个分片可以有多个副本 replica. 文档: ...

  3. Fragment为什么须要无参构造方法

    日前在项目代码里遇到偷懒使用重写Fragment带参构造方法来传参的做法,顿生好奇,继承android.support.v4.app.Fragment而又不写无参构造方法不是会出现lint错误编译不通 ...

  4. 【leetcode每日两题】-Day1-简单题

    1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元素 ...

  5. 实验09——java基于TCP实现客户端与服务端通信

    TCP通信         需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手        底层通过 流 发送数据 数据没有大小限制        可靠的传输机制 - 丢包重发 包的顺序的 ...

  6. 一文说通C#中的异步编程补遗

    前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程.   一.C#中的异步编程演变 1. ...

  7. C++基础面试题及答案

    C++ C++ 和C的主要区别 C语言是面向过程编程,C++是面向对象编程,C++ 完全兼容C C++有哪些特性,简述对他们的理解 封装.继承.多态 封装 将的事物抽象成一个个集合(也就是所说的类), ...

  8. 12、Decorator 装饰器 模式 装饰起来美美哒 结构型设计模式

    1.Decorator模式 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式(Decorator Pattern)允许向一个现 ...

  9. sftp与ftp的区别

    SFTP和FTP非常相似,都支持批量传输(一次传输多个文件),文件夹/目录导航,文件移动,文件夹/目录创建,文件删除等.但还是存在着差异,下面我们来看看SFTP和FTP之间的区别. 1. 安全通道FT ...

  10. C#LeetCode刷题-贪心算法

    贪心算法篇 # 题名 刷题 通过率 难度 44 通配符匹配   17.8% 困难 45 跳跃游戏 II   25.5% 困难 55 跳跃游戏   30.6% 中等 122 买卖股票的最佳时机 II C ...