#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSharedMemory> //共享内存
#include <QFileDialog>
#include <QPixmap>
#include <QMessageBox>
#include <QDataStream>
#include <QDebug>
#include <QBuffer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_loadFromfile_clicked();
void on_loadFromMomory_clicked();
private:
Ui::MainWindow *ui;
QSharedMemory *memory; //共享内存指针 QSharedMemory shareMemory;//注意该变量不要在函数内局部定义,由于函数内的局部变量随着函数执行结束而消失
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
/*
向共享内存中提供数据的一方:
1,定义QSharedMemory shareMemory,并设置标志名shareMemory.setKey();
2,将共享内存与主进程分离 shareMemory.detach();
3,创建共享内存 shareMemory.create();
4,将共享内存上锁shareMemory.lock();
5,将进程中要共享的数据拷贝到共享内存中;
6,将共享内存解锁shareMemory.unlock();
从共享内存中取数据的一方:
1,定义QSharedMemory shareMemory,并设置共享内存的标志名shareMemory.setKey()注意设置的要与提供内存共享的一方要一样。
2,将共享内存上锁shareMemory.lock();
3,将共享内存与主进程绑定shareMemory.attach(),使该进程可以访问共享内存的数据;
4,从共享内存中取数据;
5,使用完后将共享内存解锁shareMemory.unlock(),另外将共享内存与该进程分离shareMemory.detach();
*/
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
memory = new QSharedMemory;
memory->setKey("share"); //定义QSharedMemory shareMemory,并设置标志名shareMemory.setKey();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_loadFromfile_clicked()
{
//判断是否存在共享内存
if(this->memory->isAttached())
this->memory->detach();// 将共享内存与主进程分离 shareMemory.detach();
/*getOpenFileName(QWidget *parent = Q_NULLPTR,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),//默认自己寻找路径
QString *selectedFilter = Q_NULLPTR,
Options options = Options());*/
//QString file=QFileDialog::getOpenFileName(this,"Open Image",QString(),tr("Image(*.png,*.bmp,*.jpg)")); //筛选条件 过滤文本
QString file = QFileDialog::getOpenFileName(this);
QImage image; //将一个图像文件的名称家在到图片对象中
if(! image.load(file))
{
QMessageBox::information(this,"Error Message","Image load Error");
return;
}
//QBuff 是一个文件读写界面,但文件在内存中
//QTextStream in()
QBuffer buffer; //是一个文件 可以打开存储图片的数据
bool ok=buffer.open(QIODevice::ReadWrite); //打开文件
if(ok)
{
//QDateStream in(); 文件流
QDataStream in(&buffer); // QDateStream in(file) 此初始化数据流对象
in<<image; //把buffer中的数据读如流
}
else
{
QMessageBox::information(this,"Error Messsage", "Write buffer error");
}
int size = buffer.size();
if(!memory->create(size))
{
qDebug()<<tr("can't create memory segment");
qDebug()<<memory->error();
return;
}
qDebug()<<memory->size();
memory->lock();
char *to = (char*)memory->data(); //指向共享内存
const char *from = (char*)buffer.data().data(); //指向缓冲区
memcpy(to,from,qMin(size,memory->size()));//数据从该进程中拷贝到共享数据内存中
memory->unlock();//共享内层解锁
}
void MainWindow::on_loadFromMomory_clicked()
{
if(!memory->attach())//将shareMemory与该进程绑定使之可以访问shareMemory里的内容
{
qDebug()<<tr("can't attach share memory");
}
QBuffer buffer;
QDataStream in(&buffer); //定义一个数据流对象
QPixmap pixMap;
memory->lock();//给shareMemory枷锁
qDebug()<<memory->size();
buffer.setData((char*)memory->constData(),memory->size());//将shareMemeory里的数据放到buffer里
buffer.open(QBuffer::ReadWrite);
in>>pixMap;
memory->unlock();//将shareMemory解锁
memory->detach();//将shareMemeory与该进程分离
ui->label->setPixmap(pixMap);
}