Qt实战案例(40)——利用QSharedMemory类实现进程间通信的功能

目录

    • 一、项目介绍
    • 二、项目基本配置
    • 三、UI界面设计
    • 四、主程序实现
      • 4.1 widget.h头文件
      • 4.2 widget.cpp源文件
    • 五、效果演示

一、项目介绍

利用QSharedMemory类实现进程间通信,使用共享内存,它实现的功能是:先将一张图片写入到共享内存段中,然后再从共享内存段读出该图片。

二、项目基本配置

新建一个Qt案例,项目名称为“IPCTest”,基类选择“QWidget”,点击选中创建UI界面复选框,完成项目创建。

三、UI界面设计

UI界面布局如下:
Qt实战案例(40)——利用QSharedMemory类实现进程间通信的功能_第1张图片
界面中创建了3个控件,其名称和类型如下:

序号 名称 类型 属性
loadFromFile QPushButton text:从文件中加载图片
loadFromMemory QPushButton text:从共享内存中加载图片
label QLabel /

四、主程序实现

4.1 widget.h头文件

头文件中声明了一个私有对象、一个私有函数和两个私有槽函数:

private:
    QSharedMemory sharedMemory;
    void detach();
    
private slots:
    void on_loadFromFile_clicked();
    void on_loadFromMemory_clicked();

4.2 widget.cpp源文件

在构造函数中设置共享内存键:

    sharedMemory.setKey("QSharedMemoryExample");//设置共享内存键,作为共享内存段的标识

首先定义将进程与共享内存段分离的函数:

//将进程与共享内存段分离
void Widget::detach()
{
    if(!sharedMemory.detach())
        ui->label->setText(tr("无法从共享内存中分离!"));//未分离成功
}

定义loadFromFile按钮点击槽函数(利用QBuffer暂存图片):

//从文件中加载图片
void Widget::on_loadFromFile_clicked()
{
    //判断该进程是否已经连接到共享内存段
    if(sharedMemory.isAttached())
        detach();

    ui->label->setText(tr("请选择一个图片文件!"));
    QString fileName=QFileDialog::getOpenFileName(0, tr("打开图片"),
                                                  QDir::currentPath(),tr("Images (*.png *.jpg *.bmp)"));
    QImage image;
    if (!image.load(fileName)){
        ui->label->setText(tr("选择的文件不是图片,请选择图片文件!"));
        return;
    }
    ui->label->setPixmap(QPixmap::fromImage(image));
    //将图片加载到共享内存
    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);//以读写方式打开
    QDataStream out(&buffer);
    out<<image;
    int size =buffer.size();//获取缓冲区大小
    //创建指定大小的共享内存段,并且将共享内存段连接到本进程中
    if (!sharedMemory.create(size)) {
        ui -> label->setText(tr("无法创建共享内存段!"));
        return;
    }
    //进行共享内存段操作之前,需要进行加锁
    sharedMemory.lock();//加锁
    char *to =(char*)sharedMemory.data();
    const char *from = buffer.data().data();
    memcpy(to,from,qMin(sharedMemory.size(), size));//将buffer对应的数据段复制到共享内存段
    sharedMemory.unlock();//解锁
}

定义loadFromMemory按钮点击槽函数:

void Widget::on_loadFromMemory_clicked()
{
    if(!sharedMemory.attach()){
        ui->label->setText(tr("无法连接到共享内存段,\n请先加载一张图片!"));
        qDebug()<<sharedMemory.error();//输出错误类型
        return;
    }

    //读取共享内存段中的数据
    QBuffer buffer;
    QDataStream in(&buffer);
    QImage image;
    sharedMemory.lock();
    buffer.setData((char *)sharedMemory.constData(),sharedMemory.size());
    buffer.open(QBuffer::ReadOnly);
    in>>image;
    sharedMemory.unlock();
    sharedMemory.detach();
    ui->label->setPixmap(QPixmap::fromImage(image));

}

五、效果演示

现在运行两次程序,在一个运行的实例上单击“从文件中加载图片”,然后选择一张图片;然后在第二个运行实例上单击“从共享内存显示图片”按钮,这时便会显示第一个实例中加载的图片:
Qt实战案例(40)——利用QSharedMemory类实现进程间通信的功能_第2张图片

如果没有看懂的话,完整代码可以参考:https://download.csdn.net/download/didi_ya/82756740


ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~

你可能感兴趣的