当前位置: 首页 > news >正文

开源 C++ QT Widget 开发(十)IPC进程间通信--共享内存

 文章的目的为了记录使用C++ 进行QT Widget 开发学习的经历。临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
 
相关链接:

开源 C++ QT Widget 开发(一)工程文件结构-CSDN博客

开源 C++ QT Widget 开发(二)基本控件应用-CSDN博客

开源 C++ QT Widget 开发(三)图表--波形显示器-CSDN博客

开源 C++ QT Widget 开发(四)文件--二进制文件查看编辑-CSDN博客

 开源 C++ QT Widget 开发(五)通讯--串口调试-CSDN博客

开源 C++ QT Widget 开发(六)通讯--TCP调试-CSDN博客

开源 C++ QT Widget 开发(七)线程--多线程及通讯-CSDN博客

开源 C++ QT Widget 开发(八)网络--Http文件下载-CSDN博客

开源 C++ QT Widget 开发(九)图表--仪表盘-CSDN博客

推荐链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章主要内容:Qt 的共享内存 (QSharedMemory) 实现的进程间通信 (IPC) 应用程序。

目录:

1.主要功能

2.源码分析

3.所有源码

4.效果演示

一、主要功能

这个应用程序实现了两个进程间通过共享内存进行通信的功能:
发送消息:将文本消息写入共享内存
接收消息:从共享内存读取消息并显示
自动检测:定时检查共享内存中是否有新消息

二、源码分析

1.  Mainwindow.h文件

使用 QSharedMemory 实现共享内存功能

使用 QTimer 定期检查共享内存

定义了三个主要槽函数对应按钮点击事件

包含共享内存设置和状态更新方法

2.  Mainwindow.cpp文件

setupSharedMemory():
尝试创建共享内存(如果不存在)
如果已存在则附加到现有共享内存
处理创建/附加失败的情况

on_sendButton_clicked():
检查并附加到共享内存
将消息和时间戳序列化到缓冲区
锁定共享内存并复制数据
更新状态并清空输入框

on_receiveButton_clicked():
从共享内存读取数据
反序列化消息和时间戳
格式化并显示接收到的消息

checkSharedMemory():
定时检查共享内存中是否有新消息
有消息时更新状态标签的样式提示用户

updateStatus():
更新状态标签并设置临时样式
3秒后恢复默认状态

三、所有源码

1.  mianwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSharedMemory>
#include <QTimer>QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_sendButton_clicked();void on_receiveButton_clicked();void on_clearButton_clicked();void checkSharedMemory();private:Ui::MainWindow *ui;QSharedMemory *sharedMemory;QTimer *checkTimer;void setupSharedMemory();void updateStatus(const QString &message);
};
#endif // MAINWINDOW_H

2.  mainwindow.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QBuffer>
#include <QDataStream>
#include <QMessageBox>
#include <QDateTime>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow), sharedMemory(new QSharedMemory("MyAppSharedMemory", this))
{ui->setupUi(this);// 设置界面初始状态ui->statusLabel->setText("就绪");ui->statusLabel->setStyleSheet("QLabel { background-color: lightgray; padding: 5px; }");// 设置共享内存setupSharedMemory();// 创建定时器定期检查共享内存checkTimer = new QTimer(this);connect(checkTimer, &QTimer::timeout, this, &MainWindow::checkSharedMemory);checkTimer->start(1000); // 每秒检查一次// 设置初始消息ui->messageEdit->setText("你好,这是来自QT共享内存的消息!");
}MainWindow::~MainWindow()
{// 清理共享内存if (sharedMemory->isAttached()) {sharedMemory->detach();}delete ui;
}void MainWindow::setupSharedMemory()
{// 尝试创建或附加到共享内存if (!sharedMemory->create(1024) && sharedMemory->error() == QSharedMemory::AlreadyExists) {if (sharedMemory->attach()) {updateStatus("已连接到现有共享内存");} else {updateStatus("无法附加到共享内存: " + sharedMemory->errorString());}} else if (sharedMemory->isAttached()) {updateStatus("已创建新的共享内存");} else {updateStatus("无法创建共享内存: " + sharedMemory->errorString());}
}void MainWindow::on_sendButton_clicked()
{if (!sharedMemory->isAttached() && !sharedMemory->attach()) {updateStatus("无法附加到共享内存: " + sharedMemory->errorString());return;}QString message = ui->messageEdit->text();if (message.isEmpty()) {QMessageBox::warning(this, "警告", "消息不能为空!");return;}// 准备数据QBuffer buffer;buffer.open(QBuffer::ReadWrite);QDataStream out(&buffer);// 写入消息和时间戳out << message;out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");// 写入共享内存sharedMemory->lock();char *to = static_cast<char*>(sharedMemory->data());const char *from = buffer.data().data();memcpy(to, from, qMin(sharedMemory->size(), static_cast<int>(buffer.size())));sharedMemory->unlock();updateStatus("消息已发送到共享内存: " + message);ui->messageEdit->clear();
}void MainWindow::on_receiveButton_clicked()
{if (!sharedMemory->isAttached() && !sharedMemory->attach()) {updateStatus("无法附加到共享内存: " + sharedMemory->errorString());return;}// 从共享内存读取数据sharedMemory->lock();QByteArray byteArray(static_cast<const char*>(sharedMemory->constData()), sharedMemory->size());sharedMemory->unlock();QBuffer buffer(&byteArray);buffer.open(QBuffer::ReadOnly);QDataStream in(&buffer);QString message;QString timestamp;in >> message >> timestamp;if (message.isEmpty()) {ui->receivedTextEdit->append("没有可用的消息");} else {QString displayText = QString("[%1] %2").arg(timestamp, message);ui->receivedTextEdit->append(displayText);updateStatus("收到新消息: " + message);}
}void MainWindow::on_clearButton_clicked()
{ui->receivedTextEdit->clear();updateStatus("已清除接收的消息");
}void MainWindow::checkSharedMemory()
{// 定期检查共享内存中是否有新数据if (!sharedMemory->isAttached() && !sharedMemory->attach()) {return;}sharedMemory->lock();QByteArray byteArray(static_cast<const char*>(sharedMemory->constData()), sharedMemory->size());sharedMemory->unlock();QBuffer buffer(&byteArray);buffer.open(QBuffer::ReadOnly);QDataStream in(&buffer);QString message;QString timestamp;in >> message >> timestamp;if (!message.isEmpty()) {// 更新状态提示有新消息ui->statusLabel->setText("有新消息可用!");ui->statusLabel->setStyleSheet("QLabel { background-color: lightgreen; padding: 5px; }");}
}void MainWindow::updateStatus(const QString &message)
{ui->statusLabel->setText(message);ui->statusLabel->setStyleSheet("QLabel { background-color: lightblue; padding: 5px; }");// 3秒后恢复普通状态QTimer::singleShot(3000, this, [this]() {ui->statusLabel->setText("就绪");ui->statusLabel->setStyleSheet("QLabel { background-color: lightgray; padding: 5px; }");});
}

3.  mainwindow.ui文件

在工程文件夹下用记事本打开

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>600</width><height>400</height></rect></property><property name="windowTitle"><string>QT共享内存IPC示例</string></property><widget class="QWidget" name="centralwidget"><layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QLabel" name="label"><property name="text"><string>发送消息:</string></property></widget></item><item><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QLineEdit" name="messageEdit"/></item><item><widget class="QPushButton" name="sendButton"><property name="text"><string>发送</string></property></widget></item></layout></item><item><widget class="QLabel" name="label_2"><property name="text"><string>接收的消息:</string></property></widget></item><item><widget class="QTextEdit" name="receivedTextEdit"/></item><item><layout class="QHBoxLayout" name="horizontalLayout_2"><item><widget class="QPushButton" name="receiveButton"><property name="text"><string>接收消息</string></property></widget></item><item><widget class="QPushButton" name="clearButton"><property name="text"><string>清除</string></property></widget></item><item><spacer name="horizontalSpacer"><property name="orientation"><enum>Qt::Horizontal</enum></property><property name="sizeHint" stdset="0"><size><width>40</width><height>20</height></size></property></spacer></item></layout></item><item><widget class="QLabel" name="statusLabel"/></item></layout></widget></widget><resources/><connections/>
</ui>

四、效果演示

输入消息

发送消息

接收消息

http://www.dtcms.com/a/361867.html

相关文章:

  • 164.在 Vue3 中使用 OpenLayers 加载 Esri 地图(多种形式)
  • Python核心技术开发指南(033)——函数的嵌套
  • matlab扫雷小游戏
  • 计算机组成原理易混知识点
  • Python3环境搭建教程 - 使用Conda工具
  • Chrome 如何清除浏览器缓存
  • MinerU环境部署
  • (Arxiv-2025)HunyuanCustom:一种面向多模态驱动的定制化视频生成架构
  • Cesium 加载桥梁3DTiles数据时,出现部分区域发暗、部分正常的现象
  • 汽车曲柄连杆机构cad+ea113+设计说明书
  • 零跑汽车8月交付57066台,同比增长超88%
  • 微算法科技(NASDAQ:MLGO)张量网络与机器学习融合,MPS分类器助力顶夸克信号识别
  • 后端Web实战-多表操作员工列表查询
  • Java基础第8天总结(map遍历、Stream流)
  • ES6新特性:JavaScript的进化装备箱[特殊字符]
  • 「日拱一码」076 深度学习——自然语言处理NLP
  • vue动态(自适应定位)表格
  • ansible临时命令实验题
  • 自动化运维-ansible中的管理机密
  • Ansible之playbook剧本
  • Docker镜像安全守护神HarborGuard
  • Shell编程入门指南
  • apollo学习之纳什均衡求解最优策略
  • MySQL 中 InnoDB 引擎的事务隔离级别与“可重复读”隔离级别下的 SQL 编写规范
  • 2025 中国算力大会精彩回顾:算力驱动未来,液冷引领革新
  • 从 Oracle 到 TiDB,通过ETL工具,高效实现数据拉通
  • HarvardX TinyML小笔记2(番外3:数据工程)(TODO)
  • 【C++游记】AVL树
  • 通过 select into outfile / load data infile 进行数据导入导出学习笔记
  • 【网络安全入门基础教程】网络安全就业方向(非常详细)零基础入门到精通,收藏这篇就够了